Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 37, средняя оценка - 4.73
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
#1

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

26.10.2011, 01:36. Просмотров 6362. Ответов 22
Метки нет (Все метки)

Всем привет!
Есть файл file.txt в кодировке windows-1251. Нужно написать программу, которая перекодирует этот файл в UTF-8.
Заранее огромное спасибо!
http://www.cyberforum.ru/cpp-beginners/thread2186256.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.10.2011, 01:36
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Кодировка файла (C++):

Кодировка текстового файла
Есть программа которая шифрует текст на основе таблицы замены (таблица замены...

Кодировка чтения файла
Здравствуйте, форумчане! Возникла небольшая прроблемка.. Читаю данные из...

Неверная кодировка при чтении из файла
Здравствуйте! Есть функция, которая читает символы из текстового файла. При...

Неверная кодировка при считывании из файла
Проблема такая, при считывание из файла идет кракозябра, как это...

Неверная кодировка при чтении из файла
Время доброе) Скажу сразу, что честно гуглил и рылся, но ответа так и не...

22
accept
4833 / 3254 / 454
Регистрация: 10.12.2008
Сообщений: 10,569
26.10.2011, 07:00 #2
можно windows-1251 перевести в юникод, а из юникода в utf-8
возможно, есть уже что-то готовое (кроме iconv в лине)
0
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 09:29 #3
zago-vlad, покопайте в сторону MultiByteToWideChar и ей обратную функцию + на форуме такой вопрос уже детально рассматривался (по памяти где-то в июле августе, найдите прада, там постов 30 и код даже я сам какой-то выкладывал), сейчас реально нет времени рыться в архивах форума...
0
igorrr37
1863 / 1481 / 749
Регистрация: 21.12.2010
Сообщений: 2,473
Записей в блоге: 11
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;
}
2
-=ЮрА=-
Заблокирован
Автор 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-ника

0
-=ЮрА=-
Заблокирован
Автор 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:Как видим на скриншоте кодировка изменилась, причём всё довольно простенько получилось
2
Миниатюры
Кодировка файла  
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
26.10.2011, 13:17  [ТС] #7
-=Юра=-, у меня при компиляции твоего кода компилятор выдает ошибки, как на скриншоте.
P.S. У меня компилятор Dev-C++, компилирую под виндой, под линуксом не пробовал.
0
Миниатюры
Кодировка файла  
igorrr37
1863 / 1481 / 749
Регистрация: 21.12.2010
Сообщений: 2,473
Записей в блоге: 11
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;
}
2
zago-vlad
13 / 8 / 1
Регистрация: 12.01.2010
Сообщений: 106
26.10.2011, 13:31  [ТС] #9
igorrr37, у меня при компиляции твоего кода компилятор выдает такие ошибки, как на этом скриншоте.
0
Миниатюры
Кодировка файла  
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).
0
igorrr37
1863 / 1481 / 749
Регистрация: 21.12.2010
Сообщений: 2,473
Записей в блоге: 11
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;
}
2
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, то мы увидим исходной текст (см. второй скрин). Т.е., текст по просту не преобразовался.

Как быть в такой ситуации?
0
Миниатюры
Кодировка файла   Кодировка файла  
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 15:01 #13
zago-vlad, посмотрите сюда
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx,
за кодировку UTF8 в MultiByteToWideChar отвечает CP_UTF8
0
igorrr37
1863 / 1481 / 749
Регистрация: 21.12.2010
Сообщений: 2,473
Записей в блоге: 11
26.10.2011, 15:08 #14
zago-vlad, странно, у меня и кодировку, и символы распознаёт
0
Миниатюры
Кодировка файла  
-=ЮрА=-
Заблокирован
Автор 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;
}
0
Миниатюры
Кодировка файла  
-=ЮрА=-
26.10.2011, 15:28
  #16

Не по теме:

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

0
igorrr37
1863 / 1481 / 749
Регистрация: 21.12.2010
Сообщений: 2,473
Записей в блоге: 11
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;
}
2
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 16:26 #18
zago-vlad, пробуй конвертер под то о чём в личке написал
1
Вложения
Тип файла: rar ConvertorUTF.rar (16.6 Кб, 47 просмотров)
-=ЮрА=-
Заблокирован
Автор FAQ
26.10.2011, 17:08 #19
Названия прог говорят сами за себя, как ты и просил system("pause") вконце нет, правда ты даже не поймёшь почему допустим не отработало то ли файла нет то ли памяти не хватило, программа мигнёт на доли секунды и всё...

PS:Командной строки в приложениях нет так что не думай что сможешь передать в них путь или имя файла они вбиті под voice.tmp - ты сам таккое задание поставил, вот
0
Вложения
Тип файла: rar ASCIIToUTF.rar (13.6 Кб, 31 просмотров)
Тип файла: rar OEMToUTF.rar (13.6 Кб, 20 просмотров)
accept
4833 / 3254 / 454
Регистрация: 10.12.2008
Сообщений: 10,569
27.10.2011, 02:04 #20
Цитата Сообщение от zago-vlad
а мне надо UTF-8 (разновидность юникода).
это не разновидность
это кодировка, которая может представлять все кодовые точки юникода, тогда как windows-1251 - это кодировка, которая может представлять лишь малую часть кодовых точек юникода
1
27.10.2011, 02:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.10.2011, 02:04
Привет! Вот еще темы с решениями:

Кодировка
Все привет #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; ...

Кодировка в C
Есть некая функция, написаная мною POS(аргумент), она делает транслит, т.е....

Кодировка
Мне нужно, чтобы консольная программа закрывалась после ввода определённой...

Кодировка
Здравствуйте. Написал программу, всё работает и ошибок нет, но в окне вывода...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru