Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[C++] sprintf + ostream 20.11.02 20:16
Автор: Green Статус: Незарегистрированный пользователь
|
Хочется выводить инф. в поток, но при этом использовать синтаксис похожий на sprintf(), т.е. форматная строка,а за ней список аргументов.
Т.е. что-то типа
osprintf( os, "value1=%u, value2=%i", val1, val2);
где os - это поток (а не файл или буфер).
Кроме того, нужно как-то организовать проверку типов на этапе компиляции. Так что что-то типа
void osprintf( ostream os, char* fmt, ...)
{
va_list args;
char buf[100];
va_start(args,fmt) ;
sprintf(buf, fmt, args);
os << buf;
}
просто так не подходит, нужна проверка типов аргументов args, но при ещё компиляции.
Может есть какие-нибудь хитрости, типа того, как у Александреску при проверке размерности типов с помощью шаблонов на этапе компиляции?
|
|
а чем fprintf не подходит? 21.11.02 08:13
Автор: vh <Дмитрий> Статус: Member
|
|
| |
тем что под потоком я понимаю ostream 21.11.02 14:42
Автор: Green Статус: Незарегистрированный пользователь
|
|
| | |
а нельзя указать его в качестве параметра fprintf-у? 21.11.02 15:54
Автор: vh <Дмитрий> Статус: Member
|
Или я не догоняю сути вопроса...объясни плиз
|
|
[C++] sprintf + ostream 21.11.02 03:24
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
> Хочется выводить инф. в поток, но при этом использовать > синтаксис похожий на sprintf(), т.е. форматная строка,а за > ней список аргументов. > Т.е. что-то типа > osprintf( os, "value1=%u, value2=%i", val1, val2); > где os - это поток (а не файл или буфер). > > Кроме того, нужно как-то организовать проверку типов на > этапе компиляции.
Ну во-первых, невозможно совместить статический контроль типов и переменный список аргументов. От чего-то придется отказаться, и я бы отказался от переменного списка - небезопасная это вещь. Во-вторых, если хочется делать статический контроль типов, то форматирование в стиле printf не проходит (типы задаются динамически). Вообще задача разделения форматирования и данных со статическим контролем типов на халяву, имхо, не решается, хотя еще можно попытаться придумать что-нибудь с препроцессором...
|
| |
[C++] sprintf + ostream 26.11.02 09:31
Автор: Illinar Статус: Незарегистрированный пользователь
|
> > Хочется выводить инф. в поток, но при этом > использовать > > синтаксис похожий на sprintf(), т.е. форматная > строка,а за > > Ну во-первых, невозможно совместить статический контроль > типов и переменный список аргументов. От чего-то придется > задача разделения форматирования и данных со статическим > контролем типов на халяву, имхо, не решается, хотя еще
Я бы на Вашем месте не стал бы делать столь громких утверждений.
А решение проблемы существует:
http://www.boost.org/libs/format/index.htm
единственное, что мне не нравится это синтаксис - оператор % не подарок, а запятую к сожалению перегружать есть не совсем корректно...
|
| | |
[C++] sprintf + ostream 27.11.02 02:34
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
> Я бы на Вашем месте не стал бы делать столь громких > утверждений. > А решение проблемы существует: > http://www.boost.org/libs/format/index.htm > единственное, что мне не нравится это синтаксис - оператор > % не подарок, а запятую к сожалению перегружать есть не > совсем корректно...
Не вижу статической проверки типов. В указанной в линке нотации она просто не нужна. То есть тип-то не указывается, он выводится. И оператор % здесь ни при чем, с таким же успехом можно было перегрузить operator <<, правда, скобки придется ставить.
Хотя, возможно, такой вариант приемлем для вопрошавшего...
Собственно, я думал о чем-то вроде следующего:
std::cout << format<char, int, double>("%1 %2 %3", 'a', 4, 2.5);
Соответствующий класс я написал за полчаса. Но минус очевиден - задание параметров шаблона громоздко, хотя и неплохо работает.
|
| |
[C++] ostream 21.11.02 12:22
Автор: amirul <Serge> Статус: The Elderman
|
Извращение все это. Синтаксис ostream-а это уже и есть форматированный вывод, но с немножко видоизмененным представлением формата.
Сравни:
printf("Hello, %s\n", name);
cout << "Hello, " << name << endl;
printf("%.8x", n);
cout << width(8) << hex << n;
И так далее. Научись пользоваться ostream-ом и тебе не придется больше задать этот вопрос. C++ - ский iostream это самая гибкая реализация форматирования со статической проверкой типов, возможностью расширения на новые типы, возможностью управления печатью при помощи манипуляторов (можно и свои манипуляторы писать). Можно даже свои потоки писать и при этом совместимость со старым кодом, работающим просто с iostream останется.
ЗЫ: Сначала я хотел предложить написать несколько классов, но по мере того как описывал, что именно надо сделать, понял, что получается именно плюсовые потоки. Чай, разработчики стандартной библиотеки тоже не лохи :-)
ЗЗЫ: Если тебе к примеру обязательно нужна строка в некотором месте (ну боишься ты что не уследишь за типами сам и объявишь int my_name; cout << "My name is " << my_name;), намиши манипулятор must_be_string() (об этом читай страуструпа или сразу iomanip), который сможет конструироваться только из char *. Ну если ты сунешь туды чего-й-то не того - компилятор в обязательном порядке матюкнется.
После этого пиши cout << "My name is " << must_be_string(my_name);
Только ИМХО это тоже изврат.
|
| | |
[CGI] [C++] ostream 21.11.02 14:19
Автор: Green Статус: Незарегистрированный пользователь
|
Проблема не в том, умею я или нет пользоваться ostream-ом. Умею.
А в том, что запись получается уж слишком корявая (плюс ко всему wchar):
os << L"<tag text=\'" << var << L"\' id=\'" << id << L"\' attr=\'" << attr << L"\'/>";
А куда как нагляднее было бы:
owprintf( L"<tag text=\'%S\' id=\'%u\' attr=\'%i\'/>", var, id, attr);
P.S. Тока не рекомендуйте XML-парсеры, специфичная задача - нужно именно так, т.е. самому и в поток.
|
| | | |
[C++] ostream 24.11.02 18:01
Автор: vim Статус: Незарегистрированный пользователь
|
> Проблема не в том, умею я или нет пользоваться ostream-ом. > Умею. > А в том, что запись получается уж слишком корявая (плюс ко > всему wchar): > > os << L"<tag text=\'" << var << L"\' > id=\'" << id << L"\' attr=\'" << attr > << L"\'/>"; > > А куда как нагляднее было бы: > > owprintf( L"<tag text=\'%S\' id=\'%u\' > attr=\'%i\'/>", var, id, attr); > > P.S. Тока не рекомендуйте XML-парсеры, специфичная задача - > нужно именно так, т.е. самому и в поток.
Несколько предложений:
1) Перегрузи для ostream оператор << (char *)
Внутри этого оператора меняй char на wchar. Тогда тебе не придеться каждый раз ставить L перед строкой типа L"Hello" << L"World"
2) Проверяй содержимое строки. Если видешь в ней символ подстановки значения (%), то не выводи ее в поток, а запоминай. После этого жди пока к тебе придут аргументы, которые должны быть туда подставлены.
Тогда сможешь пользоваться конструкцией типа:
owprintf << "<tag text=\'%S\' id=\'%u\' attr=\'%i\'/>" << var << id << attr;
Только с аргументами тебе придется уж самому разбираться...
В этом варианте должно четко выполняться:
а) аргументы идут именно в той последовательности, в которой они указаны в строке формата
б) следом за строкой с форматом ВСЕГДА идут аргументы (а не какая-нибудь другая строка)
3) Создай некий общий объект, у которого будет два потока:
первый - это строка формат, второй - поток аргументов.
Тогда формат выводишь в один стрим, а аргументы берешь из другого.
smartstream.format << "<tag text=\'%S\' id=\'%u\' attr=\'%i\'/>";
smartstream.values << var << id << attr;
А вобще не знаю насколько это тебе критично, но самому разбираться со строкой формата и аргументами - оно хоть и несложно, но канительно...
|
| | | |
От дублирования данных в любом случае придется отказаться 22.11.02 12:56
Автор: amirul <Serge> Статус: The Elderman
|
Имхо, насколько я знаю, указать тип и в строке и в переменной и после этого заставить компилер искать соответсвия не получится.
Максимум чего можно добиться перегрузкой, препроцессором, чем угодно еще - чего-нить похожего на паскальный Write - там сама переменная в нужном месте уже специфицирует свой тип.
Ну или можно использовать RTTI и переписать какой-нить sprintf под динамическую проверку :-)))
|
| | | |
[C++] [CGI] [C++] А что, принципиально нужно писать CGI на C++? :) 21.11.02 15:28
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
На Perl, например, описанной проблемы просто нет.
|
| | | | |
[C++] Гы! Это я профиль нечаянно не тот поставил. 21.11.02 20:08
Автор: Green Статус: Незарегистрированный пользователь
|
> На Perl, например, описанной проблемы просто нет.
CGI здесь непричем, просто я случайно профиль не тот влепил. :о)
Ох уж эти мышки с колесиком.... :о)
|
|
|