Юникод против многобайтовых - PullRequest
13 голосов
/ 09 февраля 2010

Я действительно смущен этим Unicode против многобайтовой вещи.

Допустим, я компилирую свою программу в Unicode (но, в конечном счете, я хочу решение, которое не зависит от используемого набора символов).

1) Будут ли все символы 'char' интерпретироваться как широкие символы?

2) Если у меня есть простое выражение printf, то есть printf ("Hello World \ n"); без строк символов, могу ли я просто оставить это без использования _tprintf и _T ("...")? Если оператор printf содержит символьную строку, то я должен использовать _tprintf и _T ("..."), то есть _tprintf ("Hello% s \ n", name);

3) Если у меня есть текстовый файл (сохраненный в формате по умолчанию, т.е. без изменения используемого набора символов по умолчанию), который я хочу прочитать в буфер, могу ли я по-прежнему использовать символ вместо TCHAR? Особенно, если я читаю это символ за символом, то есть увеличивая указатель символа?

Спасибо.

С уважением, Rayne

Ответы [ 3 ]

4 голосов
/ 09 февраля 2010

Во-первых, если вы компилируете с UNICODE / _UNICODE и не собираетесь использовать другие платформы, вы можете избежать использования бизнеса TCHAR и использовать WCHAR (или wchar_t) и W работает везде.

1) Будут ли все символы 'char' интерпретироваться как широкие символы?

char в C - по определению - 1 байт. (Технически это не исключает его использования в качестве «широкого символа» на платформах, где wchar_t также равен 1 байту, но, учитывая, что вы используете MSVC и ориентированы на платформы Windows, это не будет иметь место.)

Так что для практических целей ответ на этот вопрос: нет.

2) Если у меня есть простое выражение printf, то есть printf ("Hello World \ n"); без строк символов, могу ли я просто оставить это без использования _tprintf и _T ("...")? Если оператор printf содержит символьную строку, то я должен использовать _tprintf и _T ("..."), то есть _tprintf ("Hello% s \ n", name);

Если вы печатаете строковые литералы ASCII, вы можете продолжить использовать printf.

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

3) Если у меня есть текстовый файл (сохраненный в формате по умолчанию, т.е. без изменения используемого набора символов по умолчанию), который я хочу прочитать в буфер, могу ли я по-прежнему использовать char вместо TCHAR? Особенно, если я читаю это символ за символом, то есть увеличивая указатель символа?

Что такое "формат по умолчанию"?

Когда вы читаете во внешнем файле, вы должны сначала прочитать первые несколько байтов, чтобы проверить наличие спецификации UTF-16 или UTF-8, а затем основывать свои решения на этом.

2 голосов
/ 09 февраля 2010

1) Будут ли все символы 'char' интерпретироваться как широкие символы?

Нет. Но все TCHAR s будут интерпретироваться как wchar_t s

Подумайте, как winnt.h, вероятно, определит это:

#ifdef UNICODE
 typedef WCHAR TCHAR;
#else
 typedef CHAR TCHAR;
#endif

Когда вы звоните SomeApi(), он будет преобразован в SomeApiA(char *arg) или SomeApiW(wchar_t *arg). (аргументы на самом деле будут TCHAR, но вы поймете))

Таким образом, ваш исходный код будет «независимым» в том смысле, что он может быть скомпилирован в версию «ANSI» или Widechar. Чтобы это работало, вам нужно использовать TCHAR вместо примитивных типов.

2) Если у меня есть простое выражение printf, то есть printf ("Hello World \ n"); без строк символов, могу ли я просто оставить это без использования _tprintf и _T ("...")? Если оператор printf содержит символьную строку, то я должен использовать _tprintf и _T ("..."), то есть _tprintf ("Hello% s \ n", name);

Я не знаю семью tprintf, кроме как могу предположить, что они работают так же, как и определения, приведенные выше. То есть tprintf принимает TCHAR в качестве аргумента и зависит от параметра UNICODE, либо обрабатывает их как char с, либо wchar_t с.

3) Если у меня есть текстовый файл (сохраненный в формате по умолчанию, то есть без изменения используемого набора символов по умолчанию), который я хочу прочитать в буфер, могу ли я по-прежнему использовать char вместо TCHAR? Особенно, если я читаю это символ за символом, то есть увеличивая указатель символа?

Какой символ, кодирующий содержимое файла, полностью зависит от него и не имеет ничего общего с TCHAR. TCHAR для имен файлов и таких, которые вы используете в вызовах Win32 API.

0 голосов
/ 09 февраля 2010

Допустим, я компилирую свою программу в Unicode (но, в конечном счете, я хочу решение, которое не зависит от используемого набора символов).

Это будет зависеть от вашего языка - например, от языка программирования, а не от человека. Что вы подразумеваете под «компиляцией моей программы в Юникоде»?

  1. Будут ли все символы 'char' интерпретироваться как широкие символы?

    • Это зависит от языка и выбранных опций. Например, Java использует 16-битные символы (для хранения UTF-16 или UCS-2 - когда-то давно это был UCS-2, но я предполагаю, что теперь это UTF-16). В C вам придется потрудиться, чтобы базовый тип 'char' интерпретировался как что-то кроме 8-битной величины - по крайней мере, на компиляторах на основе Unix.
  2. Если у меня есть простое выражение printf, то есть printf ("Hello World \ n"); без строк символов, могу ли я просто оставить это без использования _tprintf и _T ("...")? Если оператор printf содержит символьную строку, то я должен использовать _tprintf и _T ("..."), то есть _tprintf ("Hello% s \ n", name);

    • Это требует некоторого понимания платформы, на которой вы работаете, поскольку она далека от стандартной. Я подозреваю, что это MSVC ... что затрудняет мне быть авторитетным, так как я не использую MSVC. Однако стандарт ISO C99 (который не поддерживается MSVC) предоставляет такие функции, как fwprintf(), для печати строк широких символов. Если вам нужна информация о конкретном компиляторе, пометьте свой вопрос правильной информацией.
  3. Если у меня есть текстовый файл (сохраненный в формате по умолчанию, то есть без изменения используемого набора символов по умолчанию), который я хочу прочитать в буфер, могу ли я по-прежнему использовать char вместо TCHAR? Особенно, если я читаю это символ за символом, то есть увеличивая указатель символа?

    • Опять же, TCHAR не является стандартным - он очень специфичен для MSVC. В стандарте C файловый поток приобретает «ориентацию» (широкую или байтовую), когда вы применяете к нему соответствующие функции. Он остается в этой ориентации до тех пор, пока не будет закрыт (или снова открыт с помощью freopen()).
...