LINUX.ORG.RU

[C++] Как в плюсах принято делать s*printf?

 


0

2

Нужен «правильный» аналог s*printf. Вроде есть в плюсах stringstream, и из него можно брать числа, строки и т.п., т.е. что-то вроде sscanf. А нужно наоборот из примитивных значений сконструировать строку.

★★★★★

Ответ на: комментарий от pathfinder

> Так ведь хотели работу со своими типами в snprintf().

)) а вы пробовали карбюратор через выхлопную трубу чистить?

namezys ★★★★
()
Ответ на: комментарий от anonymous

2facepalm

Так заинтересовала моя личность? Пишите в почту aivanov(злая собака)keldysh(жирная точка)ru.

Нет, я НЕ порофессиноал в С++, выше была описка, знаток уже русского языка поправил.

AIv ★★★★★
()
Ответ на: комментарий от pathfinder

+1

Чудес не бывает, понятно что для своего типа придется в любом случае писать какой то вывод в строку. Обзовите его напр. c_str() и с-но все... у меня был выше вопрос о сборке мусора в этом случае, пока ничего нового не услышал.

AIv ★★★★★
()
Ответ на: комментарий от AIv

> у меня был выше вопрос о сборке мусора в этом случае, пока ничего нового не услышал.

Повтори его?

c_str возращает буфер, который живет внутри объекта string и валиден до следующей неконстантной операции с объектов string (или до его деструктурирования)

namezys ★★★★
()
Ответ на: комментарий от panter_dsd

> А ты на сколько бы ограничил? И всегда бы прокатывало твое ограничение?

Капитан Очевидность подсказывает, что исходя из максимального кол-ва десятичных цифр в int.

anonymous
()
Ответ на: комментарий от anonymous

А если потом внезапно нужно на long перейти? Сколько поправок придется сделать?

panter_dsd ★★★★
()
Ответ на: комментарий от namezys

у меня есть некий класс, у которого есть метод const char* c_str() возвращающий пойнтер на буфер содержащий форматированное представление объекта. Предполагается использование

myclass a;

printf("... %s...", a.c_str() );

Как это реализовать корректно с т.з. сборки мусора (на стеке c_str вроде низя, в куче - а кто его потом уберет?). Хранить представление внутри самого объекта нельзя - объекты маленькие, и их много. Я пока сделал глобальный кольцевой буфер, но интересно есть ли еще варианты.

AIv ★★★★★
()
Ответ на: комментарий от namezys

Я хочу примерно того же что и ТС - простой вывод для своих типов;-)

Учитывая специфику задачи, я лучшего варианта не нашел, ну а что касается правильности желаний... чего ж вы хоите с дилетнта то? Мне бы что б работало... ;-)))

AIv ★★★★★
()
Ответ на: комментарий от namezys

> Нет. У вас не правильные желания: вы хотите вернуть объект, которым не кто не владеет

AIv'у уже предлагали возвращать string, но человек упертый и хочет того чего по-хорошему сделать нельзя. Более того он еще для этого обходные решения придумывает.

anonymous
()
Ответ на: комментарий от anonymous

Implicitly shared подразумевает выделение памяти в куче, а хочется для мелких одноразовых объектов в стеке.

Вот я доработал пример, по идее память тратится только на буфер символов:

#include <stdio.h>

class A
{
public:
    enum {ToStr_BufferSize=50};
    inline void ToStr_fill(char* buf)
    {
        buf[0]='A';
        buf[1]='B';
        buf[2]='C';
        buf[3]='\0';
    }
};

template<typename T> class ToStr
{
public:
    char buf[T::ToStr_BufferSize];
    inline ToStr(T& obj)
    {
        obj.ToStr_fill(buf);
    }
    
    inline const char* c_str()
    {
        return buf;
    }
};

int main(int argc, char *argv[])
{
    A obj;
    
    printf("Result=%s\n",ToStr<A>(obj).c_str());
}

pathfinder ★★★★
()
Ответ на: комментарий от pathfinder

А не проще вернуть std::string и привести его к строке? ИМНО это неск громоздко в использовании, но не более громоздко чем Ваш вариант.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Переопредели std::ostream& operator<<(std::ostream& stream, const SomeObject &o)и юзай потоки.

panter_dsd ★★★★
()
Ответ на: комментарий от namezys

Еще вопрос с областью видимости. Если временный объект виден до конца выражения, то почему запрещен вариант (с-но отсюда у меня и возникло развеянное выше заблуждение, спасибо):

void myfunc( mytype& ){...}

myfunc( mytype(...) );

AIv ★★★★★
()
Ответ на: комментарий от AIv

Если не нужна скорость, то можно все делать через std::string.

pathfinder ★★★★
()
Ответ на: комментарий от AIv

> Мне бы что б работало... ;-)))

Вот все так пишут, а потом удивляются. Почему объект сам себя в iostream не может вывести?

namezys ★★★★
()
Ответ на: комментарий от pathfinder

Оверхед в смысле юзания кучи? Ну тогда наверное ой... или еще глобальный кольцевой буфер, если будет уверенность что будете своевременно оттуда доставать данные, ну и в многопоточном режиме будут траблы ес-но...

AIv ★★★★★
()
Ответ на: комментарий от AIv

> Потому что по ряду причин я не использую в данной задаче iostream.

ССБЗ

sprintf тоже тогда не используй. Пусть объект сам себя пишет куда надо

namezys ★★★★
()
Ответ на: комментарий от AIv

Если ссылка неконстантная, то через нее можно изменять объект. В вашем случае изменять временный объект нет смысла, т.е. скорее всего программист ошибся, именно поэтому такие вызовы запретили.

anonymous
()
Ответ на: комментарий от namezys

С какого перепугу он константный? Компилятор говорит

error: invalid initialization of non-const reference of type ‘A&’ from a temporary of type ‘A’

Я б его понял, если б он прибил этот временный объект до вызова ф-ии, но Вы говорите (и тесты говорят) что он его прибьет после. Где логика?

AIv ★★★★★
()
Ответ на: комментарий от namezys

> Вы пытаетесь передать константный объект в функцию

namezys, покажите, пожалуйста, где там константный объект?

anonymous
()
Ответ на: комментарий от anonymous

void make_par_file( ostream& );

make_par_file( ostream(«file.par») );

Так низя, но иногда хочется;-)

AIv ★★★★★
()
Ответ на: комментарий от AIv

> Где логика?

Логики нет когда вы пытаетесь изменить временный объект (а зачем вам еще неконстатная ссылка?).

anonymous
()
Ответ на: комментарий от AIv

Фу ты, бред написал.

В любом случае он ведет себя по стандарту. И я считаю, что правильно

namezys ★★★★
()
Ответ на: комментарий от anonymous

И я могу предложить еще тыщу вариантов вполне логичного измеенения временного объекта. Если это типа защита от дурака, то ИМНО и варнинга б хватило.

AIv ★★★★★
()
Ответ на: комментарий от AIv

> И я могу предложить еще тыщу вариантов вполне логичного измеенения временного объекта. Если это типа защита от дурака, то ИМНО и варнинга б хватило.

Еще Страуструп писал про защиту от дурака в данном случае.

anonymous
()
Ответ на: комментарий от AIv

>Вот кстати вопрос к сообществу - есть метод класса, возвращающий const char*

В плюсах за const char* в неприкрытом виде - убивать.

метод класса, возвращающий

А не лучше ли сначала написать метод класса, пишущий текстовое представление на поток? Оно по-универсальнее будет.

printf( "... %s ...", myobject.c_str() )

Убивать

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

- убивать.

Убивать

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

pathfinder ★★★★
()
Ответ на: комментарий от anonymous

>как в моём языке взаимодействуют объекты - это лишнее. Это неважно, это полностью лишнее.

Посмотрите /usr/src/linux - нет никаких C++. Почему? Потому что они не нужны

Тем не менее, в исходниках ядра объекты и полиморфизм йюзаются повсеместно

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

убивать? тогда с авторов std::string начните:-)

Про временный объект - понял, спасибо.

Ну что ж facepalm то в почту не пишет, а то я уж составил коварный план - натравить его на завкафедрой когда опять уволится попытаюсь и опять будут уговаривать остаться. А так faceplam им сразу все объянил бы про меня, и отпустили с миром... эх;-((((

AIv ★★★★★
()
Ответ на: комментарий от pathfinder

Да что тут разжевывать-то, всё и так очевидно.

Работать с голой ж^W^Wголыми указателями в плюсах - моветон. Ну, только если они к нам не приходят из всяких сишных библиотек и прочего. namezys уже об этом сказал.

C принтфом всё должно быть ещё очевиднее - он пережиток прошлого, не типизирован и вообще с эллипсисами. В плюсавых приложениях его вообще не надо использовать. Отсюда и надуманная проблема с возвращением строкового представления объекта.

Ну не предназначены функции с переменным числом аргументов для работы с плюсистскими не-PoD-типами. Противоречит это здравому смыслу.

Вот каноничное плюсавое решение: http://www.boost.org/doc/libs/1_38_0/libs/format/doc/format.html#user-defined

Синтаксически выглядит примерно так же выразительно, но при этом в разы православней и роднее для плюсов

yoghurt ★★★★★
()
Ответ на: комментарий от AIv

>тогда с авторов std::string начните:-)

Вот их как раз трогать не надо. Они постарались и написали хоть какую-то реализацию строк.

А вот тех горе-плюсистов, которые плевали на их труд и продолжают насиловать const char*, надо насильно переводить на похапе

yoghurt ★★★★★
()
Ответ на: комментарий от pathfinder

> Воистину, буст надо канонизировать. :)

посмертно

namezys ★★★★
()
Ответ на: комментарий от yoghurt

> продолжают насиловать const char*, надо насильно переводить на похапе

Это жестоко

namezys ★★★★
()
Ответ на: комментарий от yoghurt

Параметры с номерами типа %1 гораздо интереснее сишных, которые привязаны к одной своей позиции. Такие параметры с номерами позволяют делать строки для переводов на другие языки, у которых могут требоваться иной порядок следования аргументов при выводе. Сишные %s на такое не способны в принципе.

anonymous
()
Ответ на: комментарий от anonymous

Локализация и форматирование - это разные вещи

namezys ★★★★
()
Ответ на: комментарий от anonymous

Гнать таких преподов из универов поганой метлой

во-во. У меня в универе был препод, которому я показал, что в паскале можно писать так:

writeln(sin(x));
, а не
a:=sin(x);
writeln(a);
. Он охренел и сообщил, что это какое-то нововведение. в компиляторе 15летней давности.ок.

do0dlez ★★
()
Ответ на: комментарий от do0dlez

Вот у нас был препод - золото

Хакер, странный, лекции читал из головы, учил С вообще не понятно как. Но через 3 недели уже девушки в консоли бодро набирали cd m<tab><tab> gcc t.c ./a.out и прогали

namezys ★★★★
()
Ответ на: комментарий от do0dlez

Ну выгоните меня, выгоните!!! Я с ЛОР-а ржунимагу... ;-)))

Че та автор поста про «гнать...» так в почту и не написал. Персонально трясти причиндалами боясно, могут отвалицца?

AIv ★★★★★
()
Ответ на: комментарий от panter_dsd

> > максимального кол-ва десятичных цифр в int

И каково же оно?

log10(INT_MAX) + 1

А на других платформах?

log10(INT_MAX) + 1

anonymous
()
Ответ на: комментарий от yoghurt

> > как в моём языке взаимодействуют объекты - это лишнее. Это неважно, это полностью лишнее.

> Посмотрите /usr/src/linux - нет никаких C++. Почему? Потому что они не нужны

Тем не менее, в исходниках ядра объекты и полиморфизм йюзаются повсеместно

1) ООП это не С++, С++ это не ООП

2) Можно прекрасно использовать ООП на Си без гигансткого оверхеда (сам знаешь, смотреть в /usr/src/linux)

3) На С весь ООП делается прозрачно - сами объекты не создаются, нет поинтеров и ссылок - только поинтеры, язык более консистентен. Следить нужно только за объектами в системе, а не в языке + в системе (любимый некоторыми «принцип наименьшего удивления» - само по себе ничего не создаётся и не выделяется, и именно это - выделение и создание временных объектов - жуткий бред, в ядре вообще может привести к куче багов - слишком много контекстов).

4) Вывод - С++ особо не нужен.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.