C: конвертировать специальные символы ASCII ÄÖÜ - PullRequest
0 голосов
/ 30 июня 2011

Я читаю текст с сайта с Curl. Все необработанные данные возвращаются посимвольно с

return memEof(mp) ? EOF : (int)(*(unsigned char *)(mp->readptr++));

Моя проблема в том, что все специальные символы, такие как ÄÖÜäöüß и т. Д., Все неверны и выглядят очень загадочно. В настоящее время я корректирую их вручную, корректируя их значения с помощью этой таблицы:

http://www.barcoderesource.com/barcodeasciicharacters.shtml

Мне было интересно, есть ли более элегантный способ сделать это и как другие решают такие проблемы.

Ответы [ 2 ]

1 голос
/ 01 июля 2011

Это проблема с кодировкой. Если вы читаете данные побайтно, вы можете правильно и легко обрабатывать только однобайтовые кодировки (например, «семейство» ISO-8859 и многие другие), если у вас есть возможность правильно преобразовать их в целевую кодировку, если вам это нужно. Но с такими кодировками, как UTF-8, вам повезло меньше, поскольку для получения правильного кода вам нужно прочитать 1 байт, или, может быть, 2, или, может быть, три ... Если вы передаете их в строку, и выводите строку в целом, и кодировка устройства вывода совпадает с кодировкой ввода, в любом случае вы получите правильный символ, показанный.

Если этого не происходит, и вы не печатаете каждый байт так, как если бы он был символом, то кодировка устройства вывода не соответствует той, с которой записана строка.

Если выходные данные после того, как вы напечатаете строку «в целом», выглядят нормально, проблема заключается в том, что вы интерпретируете каждый байт как один символ, а это не так (у вас есть многобайтовая кодировка для символа, подобная специальной, которую вы упоминается, скорее всего, это UTF-8, но это может быть и не слишком).

Если вы получаете равные результаты в обоих случаях (когда вы печатаете каждый байт один за другим и когда вы выводите строку, содержащую всю последовательность байтов), то предполагаемое кодирование устройства вывода представляет собой однобайтовую кодировку, подобную входной кодировке, но они не совпадают.

Дополнительные сведения должны знать, как вы собираете прочитанные байты, чтобы напечатать их и сказать, что они выглядят загадочно.

Пример.

const char *string = "\xc3\xa8\xc3\xb2\xc3\xa0";
int i;
for(i = 0; string[i] != 0; i++)
{
   printf("%c\n", string[i]);
   // using \n is important; if you "sequence" the chars and the output enc is
   // utf-8, you obtain the right output
}
printf("%s", string);

Вы получите другие результаты, если кодировка устройства вывода - UTF-8; если это однобайтовая кодировка, вы получаете тот же вывод (кроме новой строки), но это «неправильно» в отношении того, что я написал, т. е. текст.

"Тот же" текст на латинице 1 "\ xe8 \ xf2 \ xe0". Latin1 - это однобайтовая кодировка, так что речь выше. Если вы печатаете на терминале с пониманием utf-8, вы можете получить что-то вроде ...

Итак, имеют значение кодировки, также важна кодировка вывода устройства / формата, и вы должны знать и то и другое, чтобы правильно обрабатывать и отображать текст. (Что касается формата, примером может быть html, где вы можете указать кодировку контента ... вы должны быть последовательны, и вы все увидите хорошо)

1 голос
/ 30 июня 2011

Полагаю, вам нужно использовать внешнюю библиотеку, такую ​​как iconv , чтобы создать строку wchar_t, содержащую данные. Это зависит от используемой кодировки символов.

...