?

Log in

No account? Create an account

Программистское полуриторическое - Общество дровосеков Бердичева по изучению Мишны

Aug. 8th, 2012

04:55 pm - Программистское полуриторическое

Previous Entry Share Next Entry


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

std::string format(const char * form, ...) {
    const int bufsize = 1024;
    char buf[bufsize];
    std::string ret;
    va_list al, al_copy;
    va_start (al,form);
    va_copy (al_copy, al);
    int need = vsnprintf(buf, bufsize, form, al) + 1;
    if (need <= bufsize) {
        ret = buf;
    } else {
        char dyn[need];
        vsprintf(dyn, form, al_copy);
        ret = dyn;
    }
    va_end(al_copy);
    va_end(al);
    return ret;
}

Comments:

(Deleted comment)
[User Picture]
From:spamsink
Date:August 9th, 2012 12:08 am (UTC)
(Link)
На риторические вопросы мы даем риторические ответы!
(Reply) (Parent) (Thread)
[User Picture]
From:yigal_s
Date:August 9th, 2012 12:05 am (UTC)
(Link)
как можно? C++ и printf - это верх некашерности!

Полагается использовать всякие streams! Уже 20 лет как.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 9th, 2012 12:09 am (UTC)
(Link)
ОК, снимаю зачеркивание.
(Reply) (Parent) (Thread)
[User Picture]
From:oldjackaroo
Date:August 9th, 2012 12:24 am (UTC)
(Link)
"Собакам и программистам не на С++ вход воспрещен"
Таким образом, предполагается, что существуют собаки, программирующие не на С++. :)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 9th, 2012 12:38 am (UTC)
(Link)
Смотря какой приоритет операций.
(Reply) (Parent) (Thread) (Expand)
(Deleted comment)
[User Picture]
From:stas
Date:August 9th, 2012 04:17 am (UTC)
(Link)
asprintf?
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 9th, 2012 04:33 am (UTC)
(Link)
Неудобно. С моим способом можно использовать format("...", ...).c_str() как r-value, и всё сработает как надо.
(Reply) (Parent) (Thread)
[User Picture]
From:vaddimka
Date:August 9th, 2012 05:41 am (UTC)
(Link)
Вообще, это плохая практика - не type safe, никакой проверки на этапе компиляции.

Лучше вот так http://pastebin.com/G1KhB4jz

потом можно писать что-то типа
std::string string = StringFormatter() << "Text " << 567;
фактически, такую конструкцию можно использовать в любом месте где ожидается строка, автоматически прикастуется
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 9th, 2012 05:52 am (UTC)
(Link)
никакой проверки на этапе компиляции

Пока я в принципе могу вызвать sprintf с теми же самыми свойствами, нет смысла создавать мне искусственные неудобства, намеренно не включая в стандартную библиотеку полезную функциональность.

Попробуйте написать строгий аналог формата "%*.*s", чтобы умел и отрицательные значения ширины поля. Интересно, во сколько строчек уложитесь.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:livejournal
Date:August 9th, 2012 07:06 am (UTC)

No title

(Link)
User baramin referenced to your post from No title saying: [...] ;  return ret; } <code> <a href="http://spamsink.livejournal.com/446926.html [...]
(Reply) (Thread)
[User Picture]
From:dz
Date:August 9th, 2012 11:24 am (UTC)
(Link)
printf пережил си, это факт. в яве он тоже уже есть.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 9th, 2012 04:55 pm (UTC)
(Link)
Ибо сказано: "Не человек для формата, а формат для человека".
(Reply) (Parent) (Thread)
From:lazyreader
Date:August 9th, 2012 11:37 am (UTC)
(Link)
http://www.boost.org/doc/libs/1_50_0/libs/format/

а если вам boost не стандарт, то я уж и не знаю.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 9th, 2012 03:11 pm (UTC)
(Link)
Буст - очевидным образом не стандарт.
(Reply) (Parent) (Thread) (Expand)
[User Picture]
From:fatoff
Date:August 9th, 2012 02:30 pm (UTC)
(Link)
Эта полезная фича (массив переменной длины на стеке) именно в C++ большей частью до сих пор была заблокирована. Я чаще не GNU компилляторы использовал. Слышал, С99 и всё такое. За такое в кроссплатформенной разработке на код-ревью могут отправить в постель без сладкого. :-p

http://en.wikipedia.org/wiki/Variable-length_array

int need = vsnprintf(buf, bufsize, form, al) + 1;
if (need <= bufsize) {
ret = buf;
} else {
char dyn[need];
vsprintf(dyn, form, al_copy);
ret = dyn;
}
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 9th, 2012 03:17 pm (UTC)
(Link)
Это так, но это - деталь реализации, пафос поста не в этом. Кстати, будь фича стандартной, компилятор мог бы делать что-то подобное даже без официально доступных пользователю VLA, с помощью какой-нибудь __builtin_alloca.
(Reply) (Parent) (Thread) (Expand)
From:fatlortroll
Date:August 11th, 2012 04:51 pm (UTC)
(Link)
Какой-то совсем лютый велосипед нарисован. Ellipsis-функция, выделение буфера фиксированного размера в ней, printf. Чем не устраивает std::stringstream, например? Если вылезти чучуть за пределы stdlib, то boost::format, а то и прям boost::spirit::karma.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 11th, 2012 08:49 pm (UTC)
(Link)
Чем не устраивает std::stringstream, например?

Функциональностью и эффективностью, очевидно. Просто ради интереса, напишите эквивалент формата "%*.*s" на stringstream.

Если вылезти чучуть за пределы stdlib, то boost::format, а то и прям boost::spirit::karma.

Понятно, что на языке программирования общего назначения можно написать что угодно. Вопрос мой не в этом.
(Reply) (Parent) (Thread)