Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
1

Формат строки в макросе

26.01.2016, 13:28. Просмотров 677. Ответов 11
Метки нет (Все метки)

Добрый день,

что-то я уже запутался. Как мне получить строку после обработки форматом для успешного вывода 59 строки при этом не поломать вывод при 57 и 58 ))

Мои пробелемы:
1) определить макросом sizeof __VA_ARGS__ можно только если типы одинаковые - а тут не так.
2) прочитать следующий аргумент после filename можно formatStr = va_arg(argList, std::string) для дальнейшего string_format(formatStr, *someHowForwardEllipsises*); но если нету параметров после filename как в 57 то обращение к памяти, что нам не принадлежит
3) а через эту фичу тыц получается только аккамулировать в строку ряд переменных через to_string и т.п. Но тогда вызов foo("Hello ", "Ivan ", 10 );

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <stdarg.h>
#include <string>
#include <string.h>
using namespace std;
 
#ifdef _WIN32
#   define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#       else
#   define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
 
 
 
#define QQQ( a, ... )   if( !(a) ){expect((#a), __FILENAME__,  __VA_ARGS__ );}
 
 
std::string string_format( const std::string fmt, ... )
{
    int size = ((int)fmt.size()) * 2 + 50;   
    std::string str;
    va_list ap;
    while(1)
    {     
        str.resize( size );
        va_start( ap, fmt );
        int n = vsnprintf( (char *)str.data(), size, fmt.c_str(), ap );
        va_end( ap );
        if(n > -1 && n < size)
        { 
            str.resize( n );
            return str;
        }
        if(n > -1)  
            size = n + 1;   
        else
            size *= 2;     
    }
    return str;
}
void expect( const std::string& expression, const std::string filename,  ... )
{
    std::string formatStr;
 
   /* va_list argList;    
    string_format( formatStr, argList );
    va_end( argList );*/
 
    cout << expression << " : " << filename << " - " << formatStr << endl;
}
 
int main()
{
    const char* const name = "Ivan";
 
    int a = 10;
    QQQ( a != 10 );                                     // Expect "a != 10 : main.cpp"
    QQQ( a != 10, "Hello" );                            // Expect "a != 10 : main.cpp - Hello"
    QQQ( a != 10, "Hello %s %d", name, a );             // Expect "a != 10 : main.cpp - Hello Ivan 10"
 
 
    std::string test = string_format( "Test: Hello %s %d", name, a );
    cout << test << endl;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.01.2016, 13:28
Ответы с готовыми решениями:

Формат командной строки
Нужно выполнить задание. Есть X потоков в которых лежит по объекту, эти объекты я в случайном...

Формат строки в кодировке Unicode?
Какой формат соответствует строке в кодировке UNICODE?

Строки с Чаром (преобразовать заданную пользователем дату в формате «дд.мм.гг» в формат «месяц дд, год»)
Преобразовать заданную пользователем дату в формате «дд.мм.гг» в формат «месяц дд, год». Например,...

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

11
1378 / 405 / 144
Регистрация: 22.10.2014
Сообщений: 872
26.01.2016, 14:54 2
rikimaru2013,
А может лучше вот так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <cassert>
 
#ifndef NDEBUG
#define assertEx(condition, statement) \
    do { \
        if (!(condition)) { statement; assert(condition); } \
    } while (false)
#else
#define assertEx(condition, statement) ((void)0)
#endif
 
int main()
{
    int a = 10;
//  assert(a != 10 && "Houston we have troubles");
    assertEx(a != 10, std::cerr << "Houston we have troubles, a=" << a << ":(:(" << std::endl;);
}
0
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
26.01.2016, 15:04  [ТС] 3
Nosey, выглядит на троечку натянуто)))

Хочу пони!
0
13520 / 7175 / 1721
Регистрация: 30.01.2014
Сообщений: 12,010
26.01.2016, 16:29 4
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
va_arg(argList, std::string)
Цитата Сообщение от 5.2.2/7
passing a potentially-evaluated argument of class type (Clause 9) having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics.
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
но если нету параметров после filename как в 57 то обращение к памяти, что нам не принадлежит
Этот вариант все равно только для POD. А так, чтобы этого избежать, парси форматную строку и вытаскивай из нее количество аргументов, прежде чем обращаться к памяти.

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
а через эту фичу тыц получается только аккамулировать в строку ряд переменных через to_string и т.п.
Не только. Это самый лучший вариант из всех возможных. Эллипсис и макросы тебе помогут лишь частично.
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Но тогда вызов foo("Hello ", "Ivan ", 10 );
Очень хочется тебя поругать за такое. Фразу-то заверши, мысль не окончена, неужели ты не видишь?
В общем, из-за этого не понятно что ты хочешь.
А вообще с помощью variadic templates можно решить все, и даже чтобы foo("Hello ", "Ivan ", 10 ) работало как написано в комментарии. Но примера я давать не буду, ибо мне лень (это не пара строк)
Хочешь пони - пиши сам!
2
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
26.01.2016, 16:53  [ТС] 5
DrOffset, задал вопрос - получил 5ь вопросов сверху)))

Цитата Сообщение от DrOffset Посмотреть сообщение
Очень хочется тебя поругать за такое. Фразу-то заверши, мысль не окончена, неужели ты не видишь?
да чего там завершать то?( Там ишлось о том, что будет распаковка всех типов в глобальную для них строку. И если парсить %s ручками тогда можно и пробемы нету) Тупо пишим велосипед с квадратными колёсами в 2016-ом году)

А то, что я пишу - сталкнулся с пробелами в знаниях - знал бы куда копать выкопал бы уже давно, знал бы что гуглить, чтобы ту лопату получил - выкопал бы. А так не лопаты, не ума))) Сижу понимаю, что как рак буду std::vector<any*> передавать как психану.
0
DrOffset
26.01.2016, 16:59
  #6

Не по теме:

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
да чего там завершать то?
Ну, например, так (это предположение, т.к. фразу твою я не понял до конца):
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
3) а через эту фичу тыц получается только аккамулировать в строку ряд переменных через to_string и т.п. Но тогда вызов foo("Hello ", "Ivan ", 10 ); не сработает.
Или так:
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
3) а через эту фичу тыц получается только аккамулировать в строку ряд переменных через to_string и т.п. Но тогда вызов foo("Hello ", "Ivan ", 10 ); не получится применить.
Ну или как-то так.

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Сижу понимаю, что как рак буду std::vector<any*> передавать как психану.
:)

0
2533 / 1193 / 357
Регистрация: 30.11.2013
Сообщений: 3,817
26.01.2016, 17:37  [ТС] 7

Не по теме:

DrOffset, ааа. Понял там слова "прийдется дольше писать и неудобно".
Типа EXPECT( someBool, "Object ", id, " has some value ", someBool, " expected ", 13, " with loeID ", someID );



Добавлено через 34 минуты
Моё пони! Красивое, розовое, никому тебя не отдам моя рыбонька!!!

Кликните здесь для просмотра всего текста

Моё пони, проваливай!
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <stdarg.h>
#include <string>
#include <string.h>
using namespace std;
 
#ifdef _WIN32
#   define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
#       else
#   define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
#endif
 
 
 
#define QQQ( a, ... )   if( !(a) ){expect((#a), __FILENAME__,  __VA_ARGS__ );}
 
 
template < typename... Args>
void expect( const std::string& expression, const std::string& filename, const char* const formatString, Args&&... args )
{
    cout << expression << " : " << filename << " ";
 
    char buff[512];
    snprintf( buff, sizeof( buff ), formatString, forward<Args>( args )... );
    std::string buffAsStdStr = buff;
 
    cout << buffAsStdStr << endl;
}
void expect( const std::string& expression, const std::string& filename )
{
    cout << expression << " : " << filename << endl;
}
 
int main()
{
    const char* const name = "Ivan";
    float id = 19.8;
    int a = 10;
    QQQ( a != 10 );                                     // Expect "a != 10 : main.cpp"
    QQQ( a != 10, "Hello" );                            // Expect "a != 10 : main.cpp - Hello"
    QQQ( a != 10, "Hello %s %d", name, a );             // Expect "a != 10 : main.cpp - Hello Ivan 10"
    QQQ( a != 10, "%f Hello %s %d", id, name, a );      // Expect "a != 10 : main.cpp - 19.8 Hello Ivan 10"
 
}

2
DrOffset
26.01.2016, 18:10
  #8

Не по теме:

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Моё пони!
Видишь, можешь когда хочешь :)
Теперь осталось решить проблему фиксированного буфера для строки и дело будет в шляпе.

0
rikimaru2013
26.01.2016, 18:19  [ТС]
  #9

Не по теме:

DrOffset, я не знал про snprintf, а у вас ледяное сердце, чтобы подсказать про него! :bye:

Да и вы кажись

Вы: парси форматную строку и вытаскивай из нее количество аргументов
Я: И если парсить %s ручками тогда можно и пробемы нету) Тупо пишим велосипед с квадратными колёсами в 2016-ом году)

0
DrOffset
26.01.2016, 18:28
  #10

Не по теме:

rikimaru2013, знания, приобретенные самостоятельно, ценнее, чем подсказки. Ты решил сейчас сразу несколько задач:
1) Разобрался как узнать новое
2) Узнал новое
3) Написал реализацию на основе новых сведений

0
rikimaru2013
26.01.2016, 18:29  [ТС]
  #11

Не по теме:

DrOffset, не уж то до этого вы считали меня за леньтяя, которого надо проучить. Как так(((

0
DrOffset
26.01.2016, 18:29     Формат строки в макросе
  #12

Не по теме:

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Да и вы кажись
Контекст не учитываешь.
Эта цитата относилась к твоей попытке доставать аргументы через va_arg. Это очевидный комментарий, а не совет :)

1
26.01.2016, 18:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.01.2016, 18:29
Привет! Вот еще темы с ответами:

Ошибка в макросе
#include &lt;iostream&gt; using namespace std; #define function(x) {\ cout&lt;&lt;x&lt;&lt;endl;\ } ...

(void) в макросе define
Добрый день! Разбираюсь со строкой: #define lua_readline(L,b,p) \ ((void)L, fputs(p, stdout),...

Сцепить строку в макросе
#define TEST(a) test ## a int main() { for(int i = 1;i&lt;=4; ++i) TEST(i); } Нужно...

Что значит запись в макросе
#define MAX(x,y) (x &gt; y ? x : y) Собсно,макрос,который находит наибольшее число. Вначале идёт...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.