Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Unicode и ASCII строковые константы

17K
19 августа 2007 года
vagran
25 / / 11.11.2006
Такая проблема: пишу библиотеку для своих приложений, которая должа компилироваться в двух версиях: Unicode и ASCII. Как это обычно и делается, определяю тип символа таким образом:
 
Код:
#ifdef mylib_unicode
typedef wchar_t mylib_char;
#else
typedef char mylib_char;
#endif

и использую его дальше для всех переменных и аргументов функций. Но как быть с константами? Я попытался сделать так:
 
Код:
#ifdef mylib_unicode
#define PFX L
#else
#define PFX
#endif
.......
mylib_char sz[]=PFX"some string";
mylib_char c=PFX'a';

но Борланд не компилирует, символ L он видит как переменную, а не префиx :(.
Констант довольно много, большие массивы строк, сравнения с символами и т.п. Очень не хочется все их определять по два раза. Может быть у кого-нибудь была подобная проблема и есть хорошее решение? Заранее благодарен.
12K
19 августа 2007 года
__AleXX__
133 / / 02.04.2007
Цитата: vagran
Такая проблема: пишу библиотеку для своих приложений, которая должа компилироваться в двух версиях: Unicode и ASCII. Как это обычно и делается, определяю тип символа таким образом:
 
Код:
#ifdef mylib_unicode
typedef wchar_t mylib_char;
#else
typedef char mylib_char;
#endif

и использую его дальше для всех переменных и аргументов функций. Но как быть с константами? Я попытался сделать так:
 
Код:
#ifdef mylib_unicode
#define PFX L
#else
#define PFX
#endif
.......
mylib_char sz[]=PFX"some string";
mylib_char c=PFX'a';

но Борланд не компилирует, символ L он видит как переменную, а не префиx :(.
Констант довольно много, большие массивы строк, сравнения с символами и т.п. Очень не хочется все их определять по два раза. Может быть у кого-нибудь была подобная проблема и есть хорошее решение? Заранее благодарен.




В VC++ я не заморачивался со своими макросами а писал _T(строковая константа).

17K
19 августа 2007 года
vagran
25 / / 11.11.2006
Спасибо, я просто не знал про _Т(). Узнал, кстати только что в MSDN. Потом в заголовочных файлах нашёл его определение:
 
Код:
#define _T(x) L ## x

теперь пытаюсь понять, как это работает :). Спасибо, проблема решена.
355
20 августа 2007 года
<SCORP>
786 / / 21.10.2006
по поводу mylib_unicode, опять же в визуальной студии это делалось без дополнительных дефайнов, а в юникодном проекте уже есть заранее определённый дефан - UNICODE
#ifdef UNICODE
...
#endif
и, опять же в той же визуальной студии был точно такой же тип, как объявляешь ты -- TCHAR
17K
20 августа 2007 года
vagran
25 / / 11.11.2006
Цитата:
по поводу mylib_unicode, опять же в визуальной студии это делалось без дополнительных дефайнов, а в юникодном проекте уже есть заранее определённый дефан - UNICODE
#ifdef UNICODE
...
#endif
и, опять же в той же визуальной студии был точно такой же тип, как объявляешь ты -- TCHAR


Версия моей библиотеки никак не должна зависеть от того, явяется ли весь проект юникодным или нет.
А по поводу вышеприведённого дефайна: порылся в спецификации C/C++ и познал для себя операторы препроцессора # и ##. Я в шоке. Никогда не думал, что можно, например, сделать так:

 
Код:
#define str(x) # x
#define INC(x) version_ ## x

#include str(INC(4).h)//после препроцессора будет #include "version_4.h"

Всё, пойду рисовать транспарант "C рулит, асм подруливает, всё остальное - отстой" :)
19K
20 августа 2007 года
Некромант
23 / / 05.12.2006
Цитата: vagran
Версия моей библиотеки никак не должна зависеть от того, явяется ли весь проект юникодным или нет.
А по поводу вышеприведённого дефайна: порылся в спецификации C/C++ и познал для себя операторы препроцессора # и ##. Я в шоке. Никогда не думал, что можно, например, сделать так:
 
Код:
#define str(x) # x
#define INC(x) version_ ## x
 
#include str(INC(4).h)//после препроцессора будет #include "version_4.h"

Всё, пойду рисовать транспарант "C рулит, асм подруливает, всё остальное - отстой" :)


Прочитав твой пост я немного засомневался и накатал такой примерчик:

 
Код:
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"iostream"[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] std::cout;[/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] str(x) # x[/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] INC(x) version_ [/SIZE][SIZE=2][COLOR=#0000ff]#[/COLOR][/SIZE][SIZE=2]# x[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] main() {[/SIZE]
[SIZE=2]cout << str(INC(4).h);[/SIZE]
[SIZE=2]}[/SIZE]

[SIZE=2]Результат: INC(4).h[/SIZE]
17K
20 августа 2007 года
vagran
25 / / 11.11.2006
Цитата:

Прочитав твой пост я немного засомневался и накатал такой примерчик:
Код:
#include"iostream"
using std::cout;
#define str(x) # x
#define INC(x) version_ ## x
int main() {
cout << str(INC(4).h);
}
Результат: INC(4).h


И правда немного не до конца я разобрался. Препроцессор после первого прохода сразу же может сделать строку и не раскрывает внутреннй макро. Попробуй так:

 
Код:
#include"iostream"
using std::cout;
#define str(x) # x
#define xstr(x) str(x)
#define INC(x) version_ ## x
int main() {
cout << xstr(INC(4).h);
}
19K
20 августа 2007 года
Некромант
23 / / 05.12.2006
Кажется, я уже говорил, что препроцессор всего лишь обрабатывает текст, первым встречает str и сморит его define, получается строка "INT(4).h", а все, что в кавычках, препроцессор не сморит.
17K
20 августа 2007 года
vagran
25 / / 11.11.2006
Цитата:
Кажется, я уже говорил, что препроцессор всего лишь обрабатывает текст, первым встречает str и сморит его define, получается строка "INT(4).h", а все, что в кавычках, препроцессор не сморит.



Не видел, где ты это говорил, но

 
Код:
#include"iostream"
using std::cout;
#define str(x) # x
#define xstr(x) str(x)
#define INC(x) version_ ## x
int main() {
cout << xstr(INC(4).h);
}

выводит version_4.h
Если посмотришь на код внимательно, то поймёшь, что после первого прохода получится str(version_4.h), а после второго "version_4.h". Всё очень просто. :)
19K
20 августа 2007 года
Некромант
23 / / 05.12.2006
Естественно, все очень просто. Немного поизвращавшись над препроцессором, можно понять его ход действий:
 
Код:
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"iostream"
[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][SIZE=2] std::cout;
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] str(x) # x
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] xstr(x) str(str(str(x)))
[/SIZE][SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] INC(x) version_ [/SIZE][SIZE=2][COLOR=#0000ff]#[/COLOR][/SIZE][SIZE=2]# x
[/SIZE][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] main() {
[/SIZE][SIZE=2][COLOR=#008000]//Сначала str(str(str(INC(4).h)))
[/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#008000]//потом аргумент str(str(str(version_4.h)))
[/COLOR][/SIZE][SIZE=2]cout << xstr(INC(4).h);
}

Сначала подставляется сам xstr, потом просматривается его аргумент, а потом все получившееся заново.
[/SIZE]
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог