用于 vsnprintf 函数统一行为的 C++ 可变参数包装器

Posted

技术标签:

【中文标题】用于 vsnprintf 函数统一行为的 C++ 可变参数包装器【英文标题】:C++ varargs wrapper for a vsnprintf function unitended behaviour 【发布时间】:2014-01-29 20:29:46 【问题描述】:

我正在尝试创建一个带有 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();

在 Windows 上打印:

东西 5698652,其他东西

在 linux 上,同样的事情,有时,根据我的测试,“other thing”指针值甚至被用作“thing %d”中的第一个“%d”(所以它打印“thing address,") 其中地址是 char*“其他东西”的地址

【问题讨论】:

va_list作为参数传递给可变参数函数不会像最初传递的那样传递参数。 好的,谢谢。有解决办法吗? 为什么要实现自己的字符串类?这似乎是一个非常糟糕的主意......因为已经有一个经过很好测试和调试的std::string 可用。 Mgetz 适用于我无法针对 libstdc++ 进行编译的项目 【参考方案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;
  

【讨论】:

以上是关于用于 vsnprintf 函数统一行为的 C++ 可变参数包装器的主要内容,如果未能解决你的问题,请参考以下文章

C++ printf %p 说明符在 Linux 和 Windows 中的行为不同

vsnprintf的作用和使用

如何使用vsprintf, vsnprintf等函数

如何使用vsprintf, vsnprintf等函数

如何使用vsprintf, vsnprintf等函数

c++