什么是替换snprintf(3)的C ++习语?

时间:2011-05-01 08:58:39

标签: c++

我有一些C ++代码需要在解析某个文件头失败时生成错误消息。在这种情况下,我需要确保标头中的某个4字节字段是“OggS”,如果不是,则返回错误消息,例如“invalid capture_pattern:'FooB';期望'OggS'”。我的代码看起来像这样:

const string OggPage::parseHeader(void) {
  read(fd, capture_pattern, sizeof(capture_pattern)); // error handling omitted
  if (strncmp(capture_pattern, CAPTURE_PATTERN, sizeof(capture_pattern)) != 0) {
    char err[256];
    snprintf(err, sizeof(err), "Failed to read %d bytes from file descriptor %d: %s\n", sizeof(capture_pattern), fd, err);
    return err;
  }

  return "Everything was A-OK!";
}

从其他数据类型构建字符串的标准C ++习惯用法是什么?我不是在这里坚持printf(3)风格的格式,所以请随意提出任何可行的方法。

5 个答案:

答案 0 :(得分:5)

您可以使用C ++标准库中的stringstreamostringstream。如果不使用更多流来从中读取值(例如,istream部分将不会被使用)ostringstream更合适。

#include <sstream>
#include <string>
#include <iostream>

int main() {
 std::stringstream str_stream;
 int number = 5;

 str_stream << " String with number " << number << std::endl;;

 std::string str = str_stream.str();
 std::cout << str; 
}

答案 1 :(得分:1)

C ++这样做的方法是std::stringstream

std::stringstream err;
err << "Failed to read " << sizeof(capture_pattern)
                         << " bytes from fd " << fd << std::endl;
return err.str();

答案 2 :(得分:1)

使用cstring中的字符串函数绝对适合阅读。它们快速,方便,而且不冗长。

要构建错误消息,您可以使用stringstream,与string类,boost::format相关的运算符,或者使用snprintf

对于简单的事情你也有boost::lexical_cast

string message = "Failed to read " + lexical_cast<string>(n) +
   " bytes from the descriptor " + lexical_cast<string>(fd) + ".";

我建议您查看this Gotw以获得理智的观点。

如果你要做很多格式化,我建议boost::format。使用lexical_cast表示简单的孤立事物,如果您有需要使用stringstream,请使用operator<<(例如自定义boost,不能使用snprintf等)。

说实话,{{1}}真的很好。

答案 3 :(得分:1)

  

正如请注意,请不要建议替换实际读数 - 我有理由在这里使用C标准库进行I / O. :)

你无法真正要求用“惯用”的方法在C ++中做某事,然后说“但我想坚持使用C标准库......

无论如何,你有三个选择。我不相信他们中的任何一个都是惯用的(因为这意味着对这是最好的方式的某种共识):

  • 坚持使用您已经使用的C API
  • 使用C ++ std::stringstream,它是标准库的iostreams部分
  • 使用Boost.Format

后者的缺点在于它依赖于第三方库,但它的优势在于它以类型安全和可扩展的方式为您提供printf - 类似语法,可以与C ++流完全互操作。

答案 4 :(得分:0)

你创建一个字符串流,用'&lt;&lt;'来写你想要的东西运算符然后使用成员函数.str()。

从字符串中获取字符串
#include <sstream>
#include <string>

using namespace std;

stringstream err;
err << "Failed to read " << sizeof(capture_pattern) << " bytes from file descriptor: " << fd << endl;
string outstr = err.str();