【问题标题】:Problem using variable argument list and string formating使用可变参数列表和字符串格式的问题
【发布时间】:2023-02-01 02:44:20
【问题描述】:

我有以下函数接受一个字符串和一个参数列表,这个想法是它作为用户的 printf。下面的函数是该函数的最小可执行示例。

string description = "";

void error(string format, ...){
    va_list arguments;
    va_start(arguments, format);
    va_list arg_copy;
    va_copy(arg_copy, arguments);

    const int32_t size = snprintf(nullptr, 0, format.c_str(), arguments) + 1;
    const unique_ptr<char[]> buffer = make_unique<char[]>(size);
    va_end(arguments);

    snprintf(buffer.get(), size, format.c_str(), arg_copy);
    va_end(arg_copy);

    description += string(buffer.get(), buffer.get() + size - 1);
}

我称它如下。

int main()
{
    int a = 123;
    error("Format %d", a);
    cout<< description;

    return 0;
}

预期输出为:格式 123

输出结果为(每次执行数字变化): 格式378812424

我想这是内存的一些问题,但我无法发现问题出在哪里。

【问题讨论】:

  • 你真的应该使用 C++ 风格的可变参数模板函数而不是 C 风格的可变参数函数。或者更好的是,考虑使用 std::ostringstreamstd::format() 代替。
  • 在这种特殊情况下,您不应该使用 vsnprintf 而不是 snprintf 吗?
  • 我的编译器不支持 std::format()
  • @PredaWnia 对于尚未原生实现 std::format() 的编译器,您可以改用 fmt.dev
  • @G.M.解决方案有效,谢谢大家。

标签: c++


【解决方案1】:

您使用了错误的打印功能。由于您使用的是va_list,因此您需要使用vsnprintf() 而不是snprintf(),例如:

string description = "";

void error(string format, ...){
    va_list arguments;
    va_start(arguments, format);

    va_list arg_copy;
    va_copy(arg_copy, arguments);
    const int32_t size = vsnprintf(nullptr, 0, format.c_str(), arg_copy) + 1;
    va_end(arg_copy);

    vector<char> buffer(size);

    vsnprintf(buffer.data(), size, format.c_str(), arguments);
    va_end(arguments);

    description.append(buffer.data(), size - 1);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 2020-03-10
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 2021-02-06
    相关资源
    最近更新 更多