информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[CGI] [C++] ostream 21.11.02 14:19  Число просмотров: 1311
Автор: 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-парсеры, специфичная задача - нужно именно так, т.е. самому и в поток.
<programming>
[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 здесь непричем, просто я случайно профиль не тот влепил. :о)
Ох уж эти мышки с колесиком.... :о)
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach