0

I'm trying to make a class with a char* ptr to where I can print data with automatic allocation.

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, ...); } 

I have the allocation, and raii things everything working ok. But my wrapper function, doesn't process the variable arguments the way I want. I'm using va_list,va_start,va_end to the best of my knowledge but it seems that is not enough.

Code:

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; } 

The reallocation, the handling of the variable "pos" and "size", everything is ok. But the formatting is wrong:

Example:

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

On windows it prints:

thing 5698652, other thing

On linux, the same thing and sometimes, from my testing, the "other thing" pointer value is even used as the first "%d" in "thing %d" (so it prints "thing address,") where address is the address of the char* "other thing"

4
  • Passing a va_listas a parameter to a variadic function does not pass the parameters as they were originally passed. Commented Jan 29, 2014 at 20:34
  • Ok, thanks. Is there a solution? Commented Jan 29, 2014 at 20:34
  • 1
    why are you implementing your own string class? This would seem a really bad idea... as there is already a very well tested and debugged std::string available. Commented Jan 29, 2014 at 20:41
  • Mgetz is for a project where I can't compile against libstdc++ Commented Jan 29, 2014 at 21:04

1 Answer 1

1

Since you cannot reuse a va_list, you should recreate it in order to repeat the print:

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; } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.