在variadic函数中调用SNPRINTF和VSNPRINTF

Call to snprintf and vsnprintf inside a variadic function

本文关键字:SNPRINTF VSNPRINTF 调用 variadic 函数      更新时间:2023-10-16

我正在尝试在variadic函数中使用variadic函数。我在互联网上检查了许多示例,但我找不到错误。

当我使用Visual Studio运行程序时,我会在调用SNPRINTF时进行访问。

这里的标题:

#pragma once
#include <cstdarg>
class Console
{
   public:
     static void writeLine(const char *s, ...);
   private:
     Console() = delete;
    ~Console() = delete;
};

类:

#include "Console.h"
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <iostream>
void Console::writeLine(const char *s...)
{
    va_list arg1, arg2;
    // Search the total length
    va_start(arg1, s);
    va_copy(arg2, arg1);
    int length = snprintf(nullptr, 0, s, arg1);
    va_end(arg1);
    size_t size = length + 1;
    char *szBuff = new char[size]; // note +1 for terminating null byte
    // Format the string
    vsnprintf(szBuff, size, s, arg2);
    va_end(arg2);
    std::cout << (const char*)szBuff << std::endl;
   delete(szBuff);
}

和主要程序:

#include "Console.h"
#include <iostream>
int main()
{
   Console::writeLine("Example with an int (%d) and a string(%s)", 10, "my string");
}

我确定我做了一个愚蠢,但是我看不出为什么它不起作用。

编辑

cout调用只是示例,我正在使用Windows的功能写入Visual Studio的控制台。这就是为什么,我正在上这类课程:要在将结果写入控制台之前格式化数据。

您正在使用错误的功能来计算缓冲区的大小。snprintf()不以va_list为输入。另外,Microsoft的vsnprintf()实现并未定义为像snprintf()一样接受NULL缓冲区作为输入。您需要使用_vscprintf()

_vscprintf返回使用指定格式的代码将参数列表指向的字符串被打印或发送到文件或缓冲区,将生成的字符数。返回的值不包括终止空字符。

另外,您无法正确释放缓冲区。由于您使用new[]分配它,因此需要使用delete[]释放它。

而是尝试一下:

void Console::writeLine(const char *s, ...)
{
    va_list arg1, arg2;
    va_start(arg1, s);
    // Search the total length
    va_copy(arg2, arg1);
    size_t size = _vscprintf(s, arg2) + 1; // note +1 for terminating null byte
    va_end(arg2);
    char *szBuff = new char[size];
    // Format the string
    vsnprintf(szBuff, size, s, arg1);
    va_end(arg1);
    std::cout << szBuff << std::endl;
    delete[] szBuff;
}