как определить макрос для преобразования объединенной строки char в строку wchar_t в C

Как и макрос _T() в Visual Studio, я определил и использовал свой собственный макрос _L следующим образом:

#define _L(x)  __L(x)
#define __L(x) L ## x

Это работает для:

wprintf(_L("abc\n"));

Но получает ошибку компиляции для:

wprintf(_L("abc\n""def\n"));

Он сообщает «Строковые литералы с символами разных типов не могут быть объединены».
Я также сделал:

#define _L2(x)  __L2(x)
#define __L2(x) L ## #x
wprintf(_L2("abc\n""def\n"));

Код компилируется, но \n не работает как управляющая последовательность новой строки. \n становится двумя символами, а вывод wprintf:

"abc\n""определение\n"

Как я могу иметь макрос для преобразования двух связанных строк символов в wchar_t? Проблема в том, что у меня есть несколько уже существующих макросов:

#define BAR  "The fist line\n" \
             "The second line\n"

Я хочу преобразовать их в строку wchar во время компиляции. Компилятор ICC в Windows.

Изменить:
Макрос _L работает в gcc, MSVC и ICC не работают, это ошибка компилятора. Спасибо @R.., чтобы прокомментировать меня.


person RolandXu    schedule 24.05.2012    source источник
comment
Если я правильно помню, макрос писать не нужно. Просто поместите строку рядом друг с другом, и они автоматически объединятся в одну. По крайней мере, это работает для gcc.   -  person nhahtdh    schedule 24.05.2012
comment
Это чисто ошибка в MSVC. Языки C позволяют объединять строки разной ширины, и в результате получается широкая строка.   -  person R.. GitHub STOP HELPING ICE    schedule 24.05.2012
comment
@nhahtdh Я не должен объединять две строки. Я хочу преобразовать контактную строку в wchar.   -  person RolandXu    schedule 24.05.2012
comment
@R.. ты прав. gcc работает нормально. Но мои MSVC и Icc этого не делают. Спасибо.   -  person RolandXu    schedule 24.05.2012
comment
Объединение с помощью L"" — это стандартный канонический способ преобразования в широкую строку.   -  person R.. GitHub STOP HELPING ICE    schedule 24.05.2012
comment
@R: где в стандарте языка вы видите, что компиляторы должны обрабатывать его определенным образом? Я не нашел, поэтому не могу считать это багом. Но, пожалуйста, просветите меня :)   -  person 0xC0000022L    schedule 24.05.2012
comment
Похоже, MSVC соответствует C89, но не C99. См. stackoverflow.com/questions/2192416/   -  person Windows programmer    schedule 25.05.2012
comment
@Windowsprogrammer Спасибо. это хорошая функция в c99, но, похоже, теперь только gcc поддерживает ее правильно.   -  person RolandXu    schedule 25.05.2012


Ответы (1)


Я не думаю, что вы можете сделать это.

Макросы просто выполняют простую обработку текста. Они могут добавить L в начале, но не могут сказать, что "abc\n" "def\n" — это две строки, к которым нужно дважды добавить L.

Вы можете добиться прогресса, если будете передавать строки макросу через запятую, а не объединять:
L("abc\n", "def\n")

Тривиально определить L, который принимает ровно две строки:
#define L2(a,b) _L(a) _L(b)
Обобщить его, чтобы иметь один макрос, который получает любое количество параметров и добавляет Ls в нужное место, возможно, но это сложнее. Вы можете найти умные макросы, делающие такие вещи, в макросах Jens Gustedt для P99.

person ugoren    schedule 24.05.2012
comment
Да, могу, если компилятор C правильно поддерживает стандарт C99, например GCC. в другом вопросе говорилось об этом stackoverflow.com/questions/2192416/ - person RolandXu; 25.05.2012
comment
@RolandXu, препроцессор не может делать то, что хочет, то есть генерировать L"abc" L"def". Компилятор может (хотя MSVC, кажется, нет) полностью обрабатывать L"abc" "def" как широкую строку. - person ugoren; 25.05.2012
comment
@ugoren Хорошо, понял. Препроцессор не может. компилятор может если поддерживает c99 - person RolandXu; 26.05.2012