Я пытаюсь создать класс с 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" (поэтому он печатает "адрес предмета"), где адрес - это адрес символа * "другое"
Поскольку вы не можете повторно использовать 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;
}
}
va_list
в качестве параметра в функцию с переменными параметрами не передает параметры, как они были первоначально переданы.