sprintf和char []与字符串

时间:2009-07-17 16:24:49

标签: c++ c

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

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

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

使用字符串的缺点:我不需要担心内存管理,易于构建。 亲:慢。

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

7 个答案:

答案 0 :(得分:14)

除非它绝对是性能关键,否则我倾向于使用std :: stringstream从其组件构建字符串,然后使用c_str()生成字符串。这是安全的,因为这种方式不存在缓冲区溢出的可能性,并且通常足够快。

如果探查器告诉我构建字符串是一个热点,那么你将不得不交换一些安全性以获得速度并开始使用类似sprintf的东西,但我宁愿避免这种情况。总的来说,我将此作为最后的手段。

答案 1 :(得分:10)

这听起来像Herb Sutter的优秀文章The String Formatters of Manor Farm

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

答案 2 :(得分:4)

来自太短缓冲区的一次崩溃将抵消从sprintf获得的所有速度节省。无论如何,我不相信它更快。即使是这样,差异是否足以让人担心呢?

答案 3 :(得分:2)

由于更简单的内存管理,我几乎总是使用stringstringstreamsprintf和其他老式C库调用太容易出错。

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

答案 4 :(得分:2)

谈到C ++和优雅,我倾向于遵循两条规则:

  1. 说出你的意思。
  2. 首先配置文件,稍后进行优化。
  3. 你在谈论串联字符串,所以这就是我想到的代码:

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

    要“说出你的意思”,我伸手去拿operator +。使用std::stringstream(一串字符串)也很不错,但是我不会立即转换另一个#include来连接字符串。我猜这是个人喜好的问题。我绝对不会想到手工构建一个原始char数组。

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

答案 5 :(得分:0)

每天早上醒来时,每次重复以下三次,每晚睡前三次:

“过早优化是所有邪恶的根源。” - Knuth

换句话说,采用安全,惯用的C ++方式。速度应该在(如果)成为一个问题时修复,而不是之前,特别是如果之前修复它会使你的代码更容易出错。

至于你的第二个问题:查看ropes

答案 6 :(得分:-1)

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

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

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

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

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