Почему printf не печатает то, чем я его кормлю? - PullRequest
5 голосов
/ 09 октября 2011
printf("%s\n", "ああ");

Это выводит:

ã‚ã‚

Что еще мне нужно сделать, чтобы правильно распечатать?

Ответы [ 4 ]

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

Предполагая, что это Unicode, скомпилируйте с компилятором C99

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

int main(void) {
  wchar_t buff[3]; // = L"ああ";
  buff[0] = buff[1] = L'\U00003042';
  buff[2] = 0;
  setlocale(LC_ALL, "");
  wprintf(L"%ls\n", buff);
  return 0;
}
4 голосов
/ 09 октября 2011

Абсолютно правильная версия должна выглядеть так:

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

int main()
{
        wchar_t *s1 = L"♠♣♥♦";
        wchar_t *s2 = L"Příšerně žluťoučký kůň";
        wchar_t *s3 = L"ああ";

        setlocale(LC_ALL,""); /* pull system locale for correct output */
        wprintf(L"%ls\n%ls\n%ls\n",s1,s2,s3); /* print all three strings */
        return 0;
}

Edit:

Как указано в комментариях R .., вы можете использовать printf вместо wprintf. Единственное ограничение заключается в том, что форматирующая строка должна быть const char* для printf вместо const wchar_t* для wprintf. Поэтому в строке форматирования нет широких символов.

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

Я думаю, вам, возможно, придется использовать wprintf, версию широких символов printf.

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

Технически, C89 не поддерживает многобайтовое кодирование для строки литералов (только ASCII), стандартные функции C могут обрабатывать ввод / вывод с другими кодировками, при условии, что они могут рассматриваться как непрозрачный большой двоичный объект.

Например, это будет правильно:

#include <stdio.h>
int main() {
    printf("%s\n", "\xe3\x81\x82\xe3\x81\x82");
}

Этот может быть неправильным (если вы ожидаете, что он напечатает количество символов):

#include <stdio.h>
#include <string.h>
int main() {
    printf("%lu\n", strlen("\xe3\x81\x82\xe3\x81\x82"));
}

Компилятор может интерпретировать ввод источника как UTF-8, но это не гарантируется. Например, GCC, похоже, правильно читает исходные файлы UTF-8:

hexdump -Cv b.c
00000000  23 69 6e 63 6c 75 64 65  20 3c 73 74 64 69 6f 2e  |#include <stdio.|
00000010  68 3e 0a 69 6e 74 0a 6d  61 69 6e 28 29 0a 7b 0a  |h>.int.main().{.|
00000020  20 20 20 20 70 72 69 6e  74 66 28 22 25 73 5c 6e  |    printf("%s\n|
00000030  22 2c 20 22 e3 81 82 e3  81 82 22 29 3b 0a 7d 0a  |", "......");.}.|
00000040

Обратите внимание, что та же строка является литералом (e3 81 82 e3 81 82) и точно такой же последовательностью байтов, которая выводится на печать:

./a.out | hexdump -Cv
00000000  e3 81 82 e3 81 82 0a                              |.......|
00000007

Если ваша локаль не UTF-8, или ваш редактор сохранил файл с кодировкой, отличной от UTF-8, я подозреваю, что результат будет другим.

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