【发布时间】:2018-05-11 22:07:56
【问题描述】:
我编写此代码是为了对 std::string 使用 sprintf 样式的格式。
#include <iostream>
#include <string>
#include <vector>
#include <stdarg.h>
std::string formatstr(const std::string &fmt, ...)
{
const char *fmt_s(fmt.c_str());
std::vector<char> buf(256);
va_list args;
va_start(args, &fmt);
auto n = -1;
while ((n = vsnprintf(&buf[0], buf.size() - 1, fmt_s, args)) == -1)
buf.resize(2 * buf.size());
va_end(args);
std::string text(&buf[0]);
return text;
}
int main(int argc, char** argv)
{
std::string s = "Instrument label: %s";
std::cout << formatstr(s, "Frequency Generator") << "\n";
return EXIT_SUCCESS;
}
输出:
仪器标签:频率发生器
它在 64 位版本中运行良好。
但是,一旦我将配置更改为 32 位,VS 编辑器就会在 va_start 下添加小红色波浪线错误行并抱怨:表达式必须是左值或 xvalue
我的 64 位版本可以正常工作是一个错误吗?还是 Visual Studio 中的一个错误,它不适用于 32 位?有什么根本区别吗?
【问题讨论】:
-
这只是一个智能感知错误还是您实际上得到了一个编译器错误?如果您关闭并重新打开已选择 32 位的项目怎么办?
-
@RetiredNinja 这不仅仅是智能感知。它实际上不会让我以 32 位编译它。我只是尝试关闭并重新打开,但它没有帮助。此外,该项目是新的和最小的 - 我只是为了测试这个代码(对于这个问题)。
-
@nvd 好的,我承认它可以被解释为重复。奇怪的是,它在 64 位版本中运行良好。我实际上已经使用它一段时间了,只是现在才在 32 位版本中尝试过。
-
使用 C++ 风格
operator<<或可变参数模板有什么问题?这比尝试使用 printf 样式要安全得多。 -
你不能用同一个 va_list 对象调用 vsnprintf 两次,因为“当这些函数调用 va_arg 宏时,返回后 ap 的值是未指定的。”也许 Windows 可以让你侥幸逃脱,但代码不会是可移植的。另外,从VS2015开始,
vsnprintf符合C99;如果缓冲区太短,它不再返回 -1。见msdn.microsoft.com/en-us/library/1kt27hek.aspx#Return%20Value
标签: c++ c visual-c++