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

Работа с кодировками файла (АНСИ и ЮТФ-8) - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 31, средняя оценка - 4.71
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
17.12.2013, 17:56     Работа с кодировками файла (АНСИ и ЮТФ-8) #1
Всем здрасти!

Подскажите пожалуйста, каким образом можно реализовать следующее:

1) Как программно преобразовать текст из ANSI в UTF-8, и наоборот из UTF-8 в ANSI?

2) Как для создаваемого файла установить кодировку UTF-8? ANSI?

3) Как, при открытии файла, можно определить его кодировку, чтобы если она не ANSI, преобразовать её в таковую?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.12.2013, 17:56     Работа с кодировками файла (АНСИ и ЮТФ-8)
Посмотрите здесь:

C++ С++ работа с текстом из файла
C++ Данные.работа с данными из файла ?
Проблемы с кодировками C++
Запись текста в файл разными кодировками C++
Работа со структурами и чтением из файла C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
17.12.2013, 18:51     Работа с кодировками файла (АНСИ и ЮТФ-8) #2
Цитата Сообщение от BESSON_off Посмотреть сообщение
2) Как для создаваемого файла установить кодировку UTF-8? ANSI?

3) Как, при открытии файла, можно определить его кодировку, чтобы если она не ANSI, преобразовать её в таковую?
По своей сути - никак. Кодировка файла - это некое подпольное знание, хранящееся вне файла. В самом файле нет никакой информации о том, какая у него кодировка. Какие-то потуги в виде специальных маркеров есть, но ни одна такая потуга не даст 100% гарантии
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
17.12.2013, 20:41     Работа с кодировками файла (АНСИ и ЮТФ-8) #3
Цитата Сообщение от BESSON_off Посмотреть сообщение
Как программно преобразовать текст из ANSI в UTF-8
Можно использовать MultiByteToWideChar(), затем полученную строку wchar_t[] преобразовать в utf-8 с помощью WideCharToMultiByte().
C++
1
2
3
4
5
6
7
8
9
10
11
12
// #include <windows.h>
    char str[50] = "фыва qwer";
 
    wchar_t wstr[50];
    int num = ::MultiByteToWideChar( 1251, MB_PRECOMPOSED, str, -1, wstr, sizeof(wstr)/sizeof(wstr[0]) );
    // Returns the number of WCHAR 
    // wstr :  44 04 4b 04 32 04 30 04 20 00 71 00 77 00 65 00 72 00 00    D.K.2.0. .q.w.e.r... 
 
    char str2[100] = {};
    num = ::WideCharToMultiByte( CP_UTF8, 0, wstr, -1, str2, sizeof(str2)/sizeof(str2[0]), 0, 0 );
    // Returns the number of bytes 
    // str2 :  d1 84 d1 8b d0 b2 d0 b0 20 71 77 65 72 00    С.С.РІР° qwer.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
17.12.2013, 23:43     Работа с кодировками файла (АНСИ и ЮТФ-8) #4
До кучи
Чем сконвертировать в русский язык такие крякозябры?
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,578
Записей в блоге: 17
18.12.2013, 01:06     Работа с кодировками файла (АНСИ и ЮТФ-8) #5
Библиотека iconv
Но в некоторых фрейморках, есть свои средства работы с кодировками (например в Qt и VCL)


Цитата Сообщение от Evg Посмотреть сообщение
По своей сути - никак. Кодировка файла - это некое подпольное знание, хранящееся вне файла. В самом файле нет никакой информации о том, какая у него кодировка. Какие-то потуги в виде специальных маркеров есть, но ни одна такая потуга не даст 100% гарантии
100% нет, особенно если текст короткий.
Но тем не менее иногда 100% результат и не нужен.
Например где-то видел подобную реализацию на основе нейронных сетей.
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
19.12.2013, 15:50  [ТС]     Работа с кодировками файла (АНСИ и ЮТФ-8) #6
Спасибо всем за участие в дискуссии...
Хочу конкретизировать проблему: скачивается блок информации из интернета, распарсивается и сохраняется информация в файл. Далее этот созданный файл использует другая программа. Так вот проблема заключается в том, что вторая программа не может получить данные из файла (они кстати на русском языке), т.к. файл создается в UTF-8.
Т.е. выходов из ситуации я вижу 2:
1) Сохранять создаваемый файл в кодировке ANSI.
2) При открытии файла другой программой, "на лету" перекодировать полученные данные из UTF-8 в ANSI.

Хотелось бы развиваться по первому сценарию, но если это не возможно, то согласен и на 2-ой вариант.

Какие есть механизмы для реализации этого? (и если можно поподробнее)
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
19.12.2013, 15:58     Работа с кодировками файла (АНСИ и ЮТФ-8) #7
У тебя есть "устная" договорённость между первой и второй программой о том, что файл в UTF8. Т.е. первая программа при формировании файла должна знать, что файл в UTF8, а вторая - должна знать это же самое, но при чтении

Можно так же использовать маркер в самом начале файла - http://ru.wikipedia.org/wiki/Byte_order_mark, но это не панацея, а нанотехнология

Добавлено через 1 минуту
Точно так же можно организовать "устную" договорённость о том, что файл должен быть в какой-то из ANSI'шных кодировок.
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,578
Записей в блоге: 17
19.12.2013, 16:31     Работа с кодировками файла (АНСИ и ЮТФ-8) #8
Что мешает непосредственное содержание блока помещать в xml или html файл, в этих форматах ведь предусмотрено указание кодировки. А значит и вторая программа при чтении будет знать что-там и в какой кодировки.

Но я бы рекомендовал сведение всех данных в UTF-8 изначально при их получении. (как бы по договоренности)
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
19.12.2013, 16:34     Работа с кодировками файла (АНСИ и ЮТФ-8) #9
Цитата Сообщение от Avazart Посмотреть сообщение
Но я бы рекомендовал сведение всех данных в UTF-8 изначально при их получении. (как бы по договоренности)
+1. Мне тоже этот способ видится наиболее правильным
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
19.12.2013, 18:17  [ТС]     Работа с кодировками файла (АНСИ и ЮТФ-8) #10
Цитата Сообщение от Avazart Посмотреть сообщение
Но я бы рекомендовал сведение всех данных в UTF-8 изначально при их получении. (как бы по договоренности)
Они и имеют кодировку при создании файла UTF-8, но я хочу переконвертировать находящееся в файле перед использованием этих данных для другой программы. Она анализирует русские символы в этом файле, а кодировка UTF-8 русские символы не хочет показывать...

Цитата Сообщение от Evg Посмотреть сообщение
вторая - должна знать это же самое, но при чтении
Как указать подобное?

Цитата Сообщение от Avazart Посмотреть сообщение
Что мешает непосредственное содержание блока помещать в xml или html файл, в этих форматах ведь предусмотрено указание кодировки. А значит и вторая программа при чтении будет знать что-там и в какой кодировки.
Как это реализовать. html меня вполне бы устроил...

P.S. что вы называете договоренностями?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
19.12.2013, 18:24     Работа с кодировками файла (АНСИ и ЮТФ-8) #11
Цитата Сообщение от BESSON_off Посмотреть сообщение
а кодировка UTF-8 русские символы не хочет показывать
Это не кодировка не хочет показывать, а твоя программа не умеет с ними работать (поскольку она думает, что это ASCII)

Цитата Сообщение от BESSON_off Посмотреть сообщение
Как указать подобное?
Это нигде не указывается. Это данность. Т.е. ты сам с собой договорился и в первой программе всегда пишешь UTF8, а во второй - читаешь UTF8
Avazart
 Аватар для Avazart
6897 / 5137 / 252
Регистрация: 10.12.2010
Сообщений: 22,578
Записей в блоге: 17
19.12.2013, 20:12     Работа с кодировками файла (АНСИ и ЮТФ-8) #12
Цитата Сообщение от Evg Посмотреть сообщение
а кодировка UTF-8 русские символы не хочет показывать
Это не кодировка не хочет показывать, а твоя программа не умеет с ними работать (поскольку она думает, что это ASCII)
BESSON_off, Это и имели ввиду под договорённостями что обе программы умеют работать с толь или иной кодировкой.
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
20.12.2013, 15:04  [ТС]     Работа с кодировками файла (АНСИ и ЮТФ-8) #13
Цитата Сообщение от Evg Посмотреть сообщение
Это нигде не указывается. Это данность. Т.е. ты сам с собой договорился и в первой программе всегда пишешь UTF8, а во второй - читаешь UTF8
Каким образом это реализовать?

Попробовал применить функцию MultiByteToWideChar следующим образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
std::ifstream fin("f:\\Romka.txt");
if (!fin)
    return 1;
 
std::string strBuffer;
char ch;
 
while(fin.get(ch))
    strBuffer+=ch;
fin.close();
 
int size = MultiByteToWideChar(CP_ACP,0,strBuffer.c_str(),-1,NULL,0);
PWSTR temp = new wchar_t[size];
MultiByteToWideChar(CP_ACP,0,strBuffer.c_str(),-1,temp,size);
 
std::wstring wstrBuffer(temp); //контейнер, который нужно заполнить UTF
 
wcerr << wstrBuffer; //почему-то ничего не выводится
Почему то не выводится через std::wcerr<<wstrBuffer, c чем связана проблема? (буфер заполняется правильно)

Также попробовал, используя функцию WideCharToMultiByte перевести символы в ANSI. Файл (test.txt) в кодировке UTF-8.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
SetConsoleOutputCP(1251);
std::wifstream wfin("f:\\test.txt");
if (!wfin)
    return -1;
 
TCHAR wch;
std::wstring wstrBuffer;
while(wfin.get(wch))
    wstrBuffer+=wch;
 
wfin.close();
 
int size = WideCharToMultiByte(CP_ACP,0,wstrBuffer.c_str(),-1,NULL,0,NULL,NULL);
PSTR temp = new char[size];
WideCharToMultiByte(CP_ACP,0,wstrBuffer.c_str(),-1,temp,size,NULL,NULL);
std::string strBuffer(temp);
cerr << endl << "STR: " << strBuffer << endl;
Почему-то все русские символы не распознались (выводятся как символы '?'), а английские символы вывелись нормально.
Что сделать, чтобы начал распознаваться русский язык в этом примере?
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
20.12.2013, 16:57     Работа с кодировками файла (АНСИ и ЮТФ-8) #14
Цитата Сообщение от BESSON_off Посмотреть сообщение
c чем связана проблема? (буфер заполняется правильно)
Всё выводится правильно, если добавить
C++
1
    setlocale( LC_ALL, "" );
Файл (test.txt) в кодировке UTF-8.
C++
1
2
3
std::wifstream wfin("f:\\test.txt");
// ... 
while(wfin.get(wch))
Один символ может кодироваться в UTF-8 различным ( 1, 2, .. ) числом байт. А здесь get(wch); считывает по 2 байта. Может оказаться, что эти 2 байта относятся к различным символам исходного текста.
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
20.12.2013, 20:36  [ТС]     Работа с кодировками файла (АНСИ и ЮТФ-8) #15
Цитата Сообщение от Alex5 Посмотреть сообщение
Один символ может кодироваться в UTF-8 различным ( 1, 2, .. ) числом байт. А здесь get(wch); считывает по 2 байта. Может оказаться, что эти 2 байта относятся к различным символам исходного текста.
И каким образом можно организовать копирование символов из файла UTF-8 в контейнер string с кодировкой ANSI?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 320
Регистрация: 30.03.2009
Сообщений: 14,125
Записей в блоге: 26
20.12.2013, 22:16     Работа с кодировками файла (АНСИ и ЮТФ-8) #16
Прочитать файл в буфер обычными байтовыми операциями, а дальше MultiByteToWideChar, WideCharToMultiByte
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
21.12.2013, 05:39  [ТС]     Работа с кодировками файла (АНСИ и ЮТФ-8) #17
Цитата Сообщение от Evg Посмотреть сообщение
Прочитать файл в буфер обычными байтовыми операциями, а дальше MultiByteToWideChar, WideCharToMultiByte
Я так и делаю, но у меня англ. символы переводятся без проблем, а русские - знаками вопроса... Нужны, как на зло, именно русские символы...
Alex5
881 / 616 / 81
Регистрация: 12.04.2010
Сообщений: 1,552
21.12.2013, 13:10     Работа с кодировками файла (АНСИ и ЮТФ-8) #18
BESSON_off, обратите внимание на первый параметр.

WideCharToMultiByte( code_page, ... ) : преобразуем куда: в code_page ( откуда: из wide char ).
MultiByteToWideChar( code_page, ... ), здесь наоборот, откуда: из code_page ( куда: to wide char ).

Пример. Преобразование из utf-8 в wide char:
C++
1
MultiByteToWideChar(CP_UTF8, ... );
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
21.12.2013, 13:40  [ТС]     Работа с кодировками файла (АНСИ и ЮТФ-8) #19
Сейчас попробую...
Кстати, а почему незаписывается в поток информация в следующем примере:
C++
1
2
3
4
5
6
setlocale(LC_ALL,"");
std::wofstream wfout ("f:\\temp.txt");
if (!wfout)
return -1;
wfout<<L"Январь"; //Тут трабл
wfout.close();
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.12.2013, 13:57     Работа с кодировками файла (АНСИ и ЮТФ-8)
Еще ссылки по теме:

Работа со строками текстового файла C++
Работа со строкой из файла C++
Создание файла и работа с ним C++

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

Или воспользуйтесь поиском по форуму:
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
21.12.2013, 13:57     Работа с кодировками файла (АНСИ и ЮТФ-8) #20
немного в сторону от темы:
бывает, что файлы маркируются спец образом (Byte order mark, BOM):
http://ru.wikipedia.org/wiki/%D0%9C%...82%D0%BE%D0%B2
Yandex
Объявления
21.12.2013, 13:57     Работа с кодировками файла (АНСИ и ЮТФ-8)
Ответ Создать тему
Опции темы

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