繁体   English   中英

sprintf和char []与字符串

[英]sprintf and char [] vs. string

我需要将const char *传递给函数。 在通过它之前,我通常需要根据一些变量来构建它。 我永远无法确定哪种方法更优雅,总体上更好:

  • 分配足够长的数组以适合文本,并使用sprintf构建最终变量并将其传递给函数。
  • 使用+运算符(并置)使用变量初始化字符串s ,然后使用s.c_str()将其传递给函数。

使用数组的缺点:可能不适合整个文本。
优点:快。

使用字符串的缺点:我不必担心易于构建的内存管理。 优点:慢。

我的第二个问题是:通常如何从其他变量字符串构建完整的字符串?

除非绝对对性能至关重要,否则我倾向于使用std :: stringstream从其组件中构建字符串,然后使用c_str()生成字符串。 这是安全的,因为这样实际上几乎没有缓冲区溢出的机会,而且通常足够快。

如果分析器告诉我建立字符串是一个热点,那么您将不得不为了速度而牺牲一些安全性,并开始使用sprintf之类的东西,但我宁愿避免这种情况。 总的来说,我会将其作为最后的选择。

这听起来确实像是Herb Sutter出色的文章The Manor Farm的String Formatters的案例。

作为记录:我自己使用std::ostringstream ,构建字符串并传递oss.str().c_str()

缓冲区太短导致的一次崩溃将抵消您从sprintf获得的所有速度节省。 我不认为它反而会更快。 即使是这样,差异是否也足以令人担忧?

由于内存管理更加简便,因此我几乎总是使用stringstringstream sprintf和其他老式C库调用很容易出错。

sprintf样式函数相对于stringstream的一个好处是,可以轻松地在运行时使用不同格式的字符串,以实现国际化。 但是,您绝对应该使用snprintf或它的其他“更安全”的变体之一。

关于C ++和优雅,我倾向于遵循两个规则:

  1. 说你的意思。
  2. 首先进行分析,然后进行优化。

您在这里谈论的是连接字符串,因此这是我想到的代码:

std::string s = s1 + s2 + s3 + s4;
foo(s.c_str());

为了“说出您的意思”,我联系operator + 使用std::stringstream (字符串流)也很不错,但是我不会立即去使用另一个#include来连接字符串。 我猜这是个人喜好问题。 我绝对不考虑手动构建原始char数组。

就性能而言,我猜测operator +可能是将字符串放在一起的最慢的方法。 但是即使是慢速的方法也可能足够快达到您的目的。

每天早晨醒来时重复三遍,每晚睡觉前重复三遍:

“过早的优化是万恶之源。” -努斯

换句话说,请遵循安全,惯用的C ++方式。 当(如果有)速度成为问题时,应该固定速度,而不是以前,尤其是如果在速度之前固定速度会使您的代码更容易出错,则应该固定速度。

至于您的第二个问题:查找绳索

您没有提到平台,但是如果您使用glibc作为标准库,则可以使用GNU扩展asprintf() ,该扩展会自动分配足够大的字符串。

有关详细信息,请参见man asprintf

更通用的方法-首先对未使用的流调用fprintf()只是为了获取返回的长度,然后分配该字符串并打印到该字符串,如下所示:

FILE *stream = tmpfile();
char *string;

string = malloc(fprintf(stream, format, param)+1);
sprintf(string, format, param);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM