wprintf UTF16 (должен быть UTF8) в Linux? - PullRequest
1 голос
/ 09 октября 2011

1 Действительно странно, что wprintf показывает 'Ω' как 3A9 (UTF16), но wctomb конвертирует wchar в CEA9 (UTF8), моя локаль по умолчанию en_US.utf8.Как сказано в man-страницах, они должны соответствовать моей локали, но wpritnf использует UTF16, почему?

выдержка из http://www.fileformat.info/info/unicode/char/3a9/index.htm

Ω в UTF

UTF-8 (hex) 0xCE 0xA9 (cea9)

UTF-16 (hex) 0x03A9 (03a9)

2 wprintf и printf просто не могут быть запущены в одной и той же программе, я должен выбрать либо wprintfили printf, почему?


См. мою программу:

#include <stdio.h>
#include <wchar.h>
#include <stdlib.h>
#include <locale.h>

int main() {
  setlocale(LC_ALL,""); // inherit locale setting from environment
  int r;
  char wc_char[4] = {0,0,0,0};
  wchar_t myChar1 = L'Ω'; //greek 

  // should comment out either wprintf or printf, they don't run together
  r = wprintf(L"char is %lc (%x)\n", myChar1, myChar1);//On Linux, to UTF16

  r = wctomb(wc_char, myChar1); // On Linux, to UTF8
  r = printf("r:%d, %x, %x, %x, %x\n", r, wc_char[0], wc_char[1], wc_char[2], wc_char[3]);
}

Ответы [ 3 ]

5 голосов
/ 09 октября 2011

Ответ на ваш второй вопрос связан с ориентацией потока . Вы не можете смешивать printf() и wprintf(), потому что они требуют разных ориентаций.

Когда процесс начинается, потоки еще не установлены. При первом вызове функции, которая использует поток, он устанавливается соответствующим образом. printf() установит ориентацию на нормальную, а wprintf() установит ее на широкую.

Неопределенное поведение - вызывать функцию, которая требует другой ориентации в качестве текущей настройки.

2 голосов
/ 09 октября 2011

Как именно вы определяете, что печатает строка wprintf? Ваш комментарий под вопросом, похоже, подразумевает, что вы просто изучаете результаты wprintf ("%x", myChar1);, который печатает внутреннее числовое значение myChar1 независимо от кодировки символов (но не независимо от набора символов - есть разница); предполагая, что ваш компилятор использует Unicode для wchar_t s внутри (я полагаю, это довольно безопасная ставка), это просто выводит кодовую точку Unicode для 'Ω', которая равна 0x3a9, независимо от различий UTF-16 и UTF-8. Чтобы определить, печатает ли wprintf UTF-16, вам нужно непосредственно проверить выходные необработанные байты (например, с hexdump(1)). Например, на моем компьютере строка wprintf выводит следующее:

63 68 61 72 20 69 73 20 ce a9 20 28 33 61 39 29 0a
c  h  a  r     i  s     Ω        (  3  a  9  )  \n

Обратите внимание, что омега кодируется в UTF-8 как байты CE A9, но числовое значение wchar_t по-прежнему равно 3A9.

0 голосов
/ 25 мая 2012

Ааа, я мог бы его найти. Вам необходимо выполнить

setlocale(LC_ALL, "")

первый. Похоже, что функции ввода / вывода wchar не учитывают переменные среды LC_.

См. http://littletux.homelinux.org/knowhow.php?article=charsets/ar01s08 для дополнительной информации.

...