Оболочка C ++ varargs для поведения, объединенного с функцией vsnprintf

0

Я пытаюсь создать класс с char * ptr, где я могу печатать данные с автоматическим распределением.

class String 
{
    char* data;
    size_t size;
    int pos;
    void init(size_t size)
    {
        this->size = size;
        data = new char[this->size+1];

        data[0] = 0;
        pos = 0;
    }

public:

String(size_t size=1)
{
    init(size);
}
    ...

    void show();
    void s_printf(char *format, ...);
}

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

Код:

void sprintf(char *format, ...)
{
    va_list args;
    va_start (args, format);

    int c = vsnprintf(&data[pos],size-pos,format,args);

    // this value is different on windows and linux (or msvc and gcc)
    if((c == -1) || (c > (size-pos)))
    {
        this->size *= 2;

        data = (char*)realloc(data,this->size);

        this->sprintf(format,args);
    }
    else
    {
        pos += c;
        data[pos] = 0;
    }

    va_end (args);

    return;
}

Перераспределение, обработка переменной "pos" и "size", все в порядке. Но форматирование неверно:

Пример:

String x;

x.sprintf("thing %d, ",123);
x.sprintf("other thing");

x.show();

На окнах он печатает:

предмет 5698652, прочее предмет

В linux то же самое, а иногда и из моего тестирования значение указателя "другая вещь" даже используется как первый "% d" в "thing% d" (поэтому он печатает "адрес предмета"), где адрес - это адрес символа * "другое"

  • 0
    Передача va_list в качестве параметра в функцию с переменными параметрами не передает параметры, как они были первоначально переданы.
  • 0
    Хорошо спасибо. Есть ли решение?
Показать ещё 2 комментария
Теги:
variadic-functions

1 ответ

1
Лучший ответ

Поскольку вы не можете повторно использовать va_list, вы должны воссоздать его, чтобы повторить печать:

void sprintf(char *format, ...)
{
  while(true)
  {
    va_list args;
    va_start (args, format);

    int c = vsnprintf(&data[pos],size-pos,format,args);

    va_end (args);

    // this value is different on windows and linux (or msvc and gcc)
    if((c == -1) || (c > (size-pos)))
    {
        this->size *= 2;
        data = (char*)realloc(data,this->size);
        continue;
    }
    else
    {
        pos += c;
        data[pos] = 0;
    }
    return;
  }
}
  • 0
    спасибо, хорошо учил

Ещё вопросы

Сообщество Overcoder
Наверх
Меню