Форум программистов, компьютерный форум CyberForum.ru

Кодировка файла - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 37, средняя оценка - 4.73
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
26.10.2011, 01:36     Кодировка файла #1
Всем привет!
Есть файл file.txt в кодировке windows-1251. Нужно написать программу, которая перекодирует этот файл в UTF-8.
Заранее огромное спасибо!
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.10.2011, 01:36     Кодировка файла
Посмотрите здесь:

Кодировка в C C++
C++ Кодировка текста в c++
Сбитая кодировка C++
Кодировка C++
Неверная кодировка при чтении из файла C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
26.10.2011, 07:00     Кодировка файла #2
можно windows-1251 перевести в юникод, а из юникода в utf-8
возможно, есть уже что-то готовое (кроме iconv в лине)
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 09:29     Кодировка файла #3
zago-vlad, покопайте в сторону MultiByteToWideChar и ей обратную функцию + на форуме такой вопрос уже детально рассматривался (по памяти где-то в июле августе, найдите прада, там постов 30 и код даже я сам какой-то выкладывал), сейчас реально нет времени рыться в архивах форума...
igorrr37
 Аватар для igorrr37
1594 / 1222 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
26.10.2011, 12:26     Кодировка файла #4
вот вручную по таблице(только кириллица и латиница), вроде работает
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include <iterator>
#include <algorithm>
 
union cyrLetter
{
    struct parts
    {
        unsigned char lowPart;
        unsigned char highPart;
    } os;
    unsigned short letter;
} ou;
 
typedef std::map<char, cyrLetter> mapAccord;
 
int main(){
    std::string strInFile("1.txt"), strOutFile("2.txt");
    std::ifstream ifs(strInFile.c_str());
    std::ofstream ofs(strOutFile.c_str());
    if(ifs && ofs)
    {
        std::string strInText((std::istreambuf_iterator<char>(ifs.rdbuf())), std::istreambuf_iterator<char>());
        ofs << (char)0xef << (char)0xbb << (char)0xbf;  // make file UTF8
 
        // fill the accordance table
        mapAccord table;
        unsigned short n = 0xd090;
        for(char c = 'А'; c <= 'п'; ++c, ++n)
        {
            ou.letter = n;
            table[c] = ou;
        }
        n = 0xd180;
        for(char c = 'р'; c <= 'я'; ++c, ++n)
        {
            ou.letter = n;
            table[c] = ou;
        }
        ou.letter = 0xd191;
        table['ё'] = ou;
        ou.letter = 0xd081;
        table['Ё'] = ou;
        //
        mapAccord::const_iterator it;
        std::for_each(strInText.begin(), strInText.end(), [&](char x)
        {
            if((it = table.find(x)) != table.end())
            {
                ofs << it->second.os.highPart << it->second.os.lowPart;
            }
            else
            {
                ofs << x;
            }
        });
        ifs.close();
        ofs.close();
    }
    else std::cerr << "File not found";
    return 0;
}
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 12:39     Кодировка файла #5
Я тут подумал кто мешает по аналогии с ostream-ским оператором перегрузить ofstream-ский
//Руссификация вывода в консоль перегрузкой оператора <<
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ostream& operator<<(ostream &stream,char* s){
    for(char* ps=s; *ps; ps++){
        if(*ps=='ё')
            stream<<char(241);
        else if(*ps=='Ё')
            stream<<char(240);
        else if(*ps>=-64 && *ps<=-17)           
            stream<<char(*ps+64+128);
        else if(*ps<0)
            stream<<char(*ps+64+176);
        else
            stream<<*ps;
    }
    return stream;
}
Запишем o
C++
1
ofstream& operator<<(ofstream &stream,char* s)
и вперёд

Не по теме:

Я всего лишь попробовать предлагаю не берусь утверждать что перегрузкой конвертнём кодировку txt-ника

-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 12:44     Кодировка файла #6
Ха вот и подтверждение моих слов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <fstream>
using namespace std;
 
//ГђГіГ±Г±ГЁГґГЁГЄГ*öèÿ
ofstream& operator<<(ofstream &stream,char* s){
    for(char* ps=s; *ps; ps++){
        if(*ps=='Вё')
            stream<<char(241);
        else if(*ps=='ВЁ')
            stream<<char(240);
        else if(*ps>=-64 && *ps<=-17)           
            stream<<char(*ps+64+128);
        else if(*ps<0)
            stream<<char(*ps+64+176);
        else
            stream<<*ps;
    }
    return stream;
}
 
int main()
{
   ofstream ofs("test.txt");
   ofs<<"ГќГІГ® ГІГҐГ±ГІ ïðîãðГ*ìêè\n";
   ofs.close();
   system("pause");
   return 0;
}
PS:Как видим на скриншоте кодировка изменилась, причём всё довольно простенько получилось
Миниатюры
Кодировка файла  
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
26.10.2011, 13:17  [ТС]     Кодировка файла #7
-=Юра=-, у меня при компиляции твоего кода компилятор выдает ошибки, как на скриншоте.
P.S. У меня компилятор Dev-C++, компилирую под виндой, под линуксом не пробовал.
Миниатюры
Кодировка файла  
igorrr37
 Аватар для igorrr37
1594 / 1222 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
26.10.2011, 13:28     Кодировка файла #8
zago-vlad, попробуй так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <fstream>
using namespace std;
 
//Руссификация
namespace my
{
    ofstream& operator<<(ofstream &stream,char* s){
        for(char* ps=s; *ps; ps++){
                if(*ps=='ё')
                        stream<<char(241);
                else if(*ps=='Ё')
                        stream<<char(240);
                else if(*ps>=-64 && *ps<=-17)
                        stream<<char(*ps+64+128);
                else if(*ps<0)
                        stream<<char(*ps+64+176);
                else
                        stream<<*ps;
        }
        return stream;
    }
}
 
int main()
{
   ofstream ofs("test.txt");
   my::operator<<(ofs, "Это тест програмки\n");
   ofs.close();
   return 0;
}
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
26.10.2011, 13:31  [ТС]     Кодировка файла #9
igorrr37, у меня при компиляции твоего кода компилятор выдает такие ошибки, как на этом скриншоте.
Миниатюры
Кодировка файла  
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
26.10.2011, 13:44  [ТС]     Кодировка файла #10
Цитата Сообщение от igorrr37 Посмотреть сообщение
zago-vlad, попробуй так
Спасибо, все заработало. Но я только сейчас заметил, что твоя прога в OEM 866 преобразовывает, а мне надо UTF-8 (разновидность юникода).

Кстати, если кому-то надо, то в OEM можно сконвертировать и с помощью CharToOem("текст",char).
igorrr37
 Аватар для igorrr37
1594 / 1222 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
26.10.2011, 13:47     Кодировка файла #11
zago-vlad, исправил
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include <iterator>
#include <algorithm>
 
union cyrLetter
{
    struct parts
    {
        unsigned char lowPart;
        unsigned char highPart;
    } os;
    unsigned short letter;
} ou;
 
typedef std::map<char, cyrLetter> mapAccord;
 
int main(){
    std::string strInFile("1.txt"), strOutFile("2.txt");
    std::ifstream ifs(strInFile.c_str());
    std::ofstream ofs(strOutFile.c_str());
    if(ifs && ofs)
    {
        std::string strInText((std::istreambuf_iterator<char>(ifs.rdbuf())), std::istreambuf_iterator<char>());
        ofs << (char)0xef << (char)0xbb << (char)0xbf;  // make file UTF8
 
        // fill the accordance table
        mapAccord table;
        unsigned short n = 0xd090;
        for(char c = 'А'; c <= 'п'; ++c, ++n)
        {
            ou.letter = n;
            table[c] = ou;
        }
        n = 0xd180;
        for(char c = 'р'; c <= 'я'; ++c, ++n)
        {
            ou.letter = n;
            table[c] = ou;
        }
        ou.letter = 0xd191;
        table['ё'] = ou;
        ou.letter = 0xd081;
        table['Ё'] = ou;
        //
        mapAccord::const_iterator it;
        for(int i = 0; i < strInText.size(); ++i)
        {
            if((it = table.find(strInText[i])) != table.end())
            {
                ofs << it->second.os.highPart << it->second.os.lowPart;
            }
            else
            {
                ofs << strInText[i];
            }
        }
    }
    else std::cerr << "File not found";
    ifs.close();
    ofs.close();
    return 0;
}
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
26.10.2011, 14:12  [ТС]     Кодировка файла #12
Цитата Сообщение от igorrr37 Посмотреть сообщение
zago-vlad, исправил
.
Спасибо, теперь компилируеться. Но есть одна проблема - твоя программа только добавляет метку UTF-8 в файл и он распознается текстовым редактором как UTF-8. Таким образом, коды символов не изменяются. Получается, что с латинскими буквами и символами прога работает, а с русскими - нет. А мне нужно конвертировать как раз русский текст. Если открыть такой файл в Notepad++, то увидим то, что на первом скрине (кодировка распозналась как UTF-8, но коды символов остались те же). Если вручную поставить кодировку ASCII, то мы увидим исходной текст (см. второй скрин). Т.е., текст по просту не преобразовался.

Как быть в такой ситуации?
Миниатюры
Кодировка файла   Кодировка файла  
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 15:01     Кодировка файла #13
zago-vlad, посмотрите сюда
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx,
за кодировку UTF8 в MultiByteToWideChar отвечает CP_UTF8
igorrr37
 Аватар для igorrr37
1594 / 1222 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
26.10.2011, 15:08     Кодировка файла #14
zago-vlad, странно, у меня и кодировку, и символы распознаёт
Миниатюры
Кодировка файла  
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 15:25     Кодировка файла #15
zago-vlad, пробуй код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <windows.h>
#include <iostream>
#include <fstream>
using namespace std;
 
int main()
{
   char str[32];
   LPWSTR  lpszW = L"ГќГІГ® ГІГҐГ±ГІ ïðîãðГ*ìêè\n";
   long uLen = WideCharToMultiByte(CP_UTF8, 0, lpszW,   -1,  NULL, NULL, NULL, NULL);
               WideCharToMultiByte(CP_UTF8, 0, lpszW, uLen,  str , uLen, NULL, NULL);
   ofstream ofs("UTF-8.txt");
   ofs<<str;
   ofs.close();
   system("pause");
   return 0;
}
Миниатюры
Кодировка файла  
-=ЮрА=-
26.10.2011, 15:28
  #16

Не по теме:

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
WideCharToMultiByte
- по моему аналогичный функционал имеет wcstombs_s, надо бы освежить в памяти

igorrr37
 Аватар для igorrr37
1594 / 1222 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
26.10.2011, 16:00     Кодировка файла #17
зависит ещё от того, в какой кодировке набит сам исходник (у меня был в windows1251, при переходе в UTF8 прога не работала), вот независимый от исходника вариант (просто убрал все русские буквы)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <string>
#include <fstream>
#include <map>
#include <iterator>
#include <algorithm>
 
union cyrLetter
{
    struct parts
    {
        unsigned char lowPart;
        unsigned char highPart;
    } os;
    unsigned short letter;
} ou;
 
typedef std::map<char, cyrLetter> mapAccord;
 
int main(){
    std::string strInFile("1.txt"), strOutFile("2.txt");
    std::ifstream ifs(strInFile.c_str());
    std::ofstream ofs(strOutFile.c_str());
    if(ifs && ofs)
    {
        std::string strInText((std::istreambuf_iterator<char>(ifs.rdbuf())), std::istreambuf_iterator<char>());
        ofs << (char)0xef << (char)0xbb << (char)0xbf;  // make file UTF8
 
        // fill the accordance table
        mapAccord table;
        unsigned short n = 0xd090;
        for(char c = char(-64); c <= char(-17); ++c, ++n)
        {
            ou.letter = n;
            table[c] = ou;
        }
        n = 0xd180;
        for(char c = char(-16); c <= char(-1); ++c, ++n)
        {
            ou.letter = n;
            table[c] = ou;
        }
        ou.letter = 0xd191;
        table[char(-72)] = ou;
        ou.letter = 0xd081;
        table[char(-88)] = ou;
        //
        mapAccord::const_iterator it;
        for(int i = 0; i < strInText.size(); ++i)
        {
            if((it = table.find(strInText[i])) != table.end())
            {
                ofs << it->second.os.highPart << it->second.os.lowPart;
            }
            else
            {
                ofs << strInText[i];
            }
        }
    }
    else std::cerr << "File not found";
    ifs.close();
    ofs.close();
    return 0;
}
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 16:26     Кодировка файла #18
zago-vlad, пробуй конвертер под то о чём в личке написал
Вложения
Тип файла: rar ConvertorUTF.rar (16.6 Кб, 44 просмотров)
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 17:08     Кодировка файла #19
Названия прог говорят сами за себя, как ты и просил system("pause") вконце нет, правда ты даже не поймёшь почему допустим не отработало то ли файла нет то ли памяти не хватило, программа мигнёт на доли секунды и всё...

PS:Командной строки в приложениях нет так что не думай что сможешь передать в них путь или имя файла они вбиті под voice.tmp - ты сам таккое задание поставил, вот
Вложения
Тип файла: rar ASCIIToUTF.rar (13.6 Кб, 30 просмотров)
Тип файла: rar OEMToUTF.rar (13.6 Кб, 20 просмотров)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2011, 02:04     Кодировка файла
Еще ссылки по теме:

Неверная кодировка при считывании из файла C++
C++ Кодировка чтения файла
Неверная кодировка при чтении из файла C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
27.10.2011, 02:04     Кодировка файла #20
Цитата Сообщение от zago-vlad
а мне надо UTF-8 (разновидность юникода).
это не разновидность
это кодировка, которая может представлять все кодовые точки юникода, тогда как windows-1251 - это кодировка, которая может представлять лишь малую часть кодовых точек юникода
Yandex
Объявления
27.10.2011, 02:04     Кодировка файла
Ответ Создать тему
Опции темы

Текущее время: 04:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru