使用printf样式的格式设置std::字符串的内容
Using printf-style formatting to set the contents of a std::string
我想把用printf类型格式化字符串格式化的文本放在C++字符串中。我想出了下面的方法,看起来很有效,但我还没有发现其他人承认使用了类似的技术,所以我想我会问为什么我不应该这样做。
#include <stdio.h>
#include <stdarg.h>
#include <string>
void stringprintf(std::string &str, char const *fmt, ...) {
va_list ap;
va_start(ap, fmt);
size_t n = vsnprintf(NULL, 0, fmt, ap);
str.resize(n + 1, ' ');
char *pStr = (char *)(str.c_str());
(void)vsnprintf(pStr, str.capacity(), fmt, ap);
va_end(ap);
}
void dumpstring(std::string &str) {
printf("Object: %08X, buffer: %08X, size: %d, capacity: %dncontents: %s==n",
&str, str.c_str(), str.size(), str.capacity(), str.c_str());
}
int main(int argc, char **argv) {
std::string str;
dumpstring(str);
stringprintf(str, "A test format. A number %d, a string %s!n", 12345, "abcdefg");
printf("%s", str.c_str());
dumpstring(str);
return 0;
}
只需使用operator[]
(即&str[0]
)而不是c_str()
。没有未定义的行为。
vsnprintf(&str[0], str.capacity(), fmt, ap);
完成后,您可能应该剪掉空终止符,因为std::string
不需要它
str.pop_back();
陷阱就在这里;
char *pStr = (char *)(str.c_str());
(void)vsnprintf(pStr, str.capacity(), fmt, ap);
阅读C++11规范草案;(在其他C++版本中似乎相似)
21.4.7.1 basic_string访问者[string.accessors]
const charT*c_str()const noexcept
const charT*data()const noexcept
…
3要求:程序不得更改字符数组中存储的任何值
据我所知,分配内存并创建一个新字符串/从缓冲区分配它是最接近的选择。
您的代码是错误的,因为它调用了未定义的行为。您正在sprintf()
上单击string::c_str()
返回的指针。但是string::c_str()
返回一个指向const char
的指针,所以您不能这样做。为什么不使用非常量char
缓冲区并从中构造字符串?
int string_printf(std::string &str, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int n = std::vsnprintf(NULL, fmt, args);
va_end(args);
char *buf = new char[n + 1];
va_start(args, fmt);
std::vsnprintf(buf, fmt, args);
va_end(args);
str = std::string(buf, n);
delete[] buf;
return n;
}
相关文章:
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 使用std::mt19937从字符串中返回一个随机单词
- 我可以重新分配/覆盖std::字符串吗
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 如何将这个std::字符串转换为std::基本字符串
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- std::字符串与 PCWSTR 的对话
- 确切地说,如何解释 std::getline(stream, string) 函数在C++中填充的字符串
- 将C++ std::string 转换为 UTF-16-LE 编码的字符串
- 使用 std::string_view 的子字符串控制台输出
- std::regex:匹配由数字和空格组成的字符串,并提取数字.如何?
- 重载 std::字符串运算符+ 用于打印枚举名称
- 从std::字符串创建OssBitString
- C++ TCP 套接字 | 无法将"std::__cxx11::字符串"转换为"const
- C 中的特殊字符的子字符串(STD :: substr)
- 是否建议将字符串std::移动到将被覆盖的容器中
- 显式指定要写入的字符串 std::ostringstream
- 如何将uint16_t转换为宽字符串(std::wstring)
- 读取和Huffman压缩4字节二进制字符串STD C++Linux环境