取代snprintf(3)的c++习惯用法是什么?

What is the C++ idiom to replace snprintf(3)?

本文关键字:习惯 惯用法 是什么 c++ snprintf 取代      更新时间:2023-10-16

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

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: %sn", sizeof(capture_pattern), fd, err);
    return err;
  }
  return "Everything was A-OK!";
}

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

您可以使用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; 
}

作为一个注意事项,请不要建议替换实际的阅读-这里我想使用C标准库进行I/O是有原因的。:)

你不能真的要求用"习惯"的方式在c++中做某事,然后说"但是我想坚持使用C标准库…

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

  • 坚持使用你已经在使用的C api
  • 使用c++ std::stringstream,它是标准库
  • 的iostreams部分的一部分。
  • 使用增加。

后者的缺点是它依赖于第三方库,但它的优点是它以类型安全和可扩展的方式为您提供了类似printf的语法,可以与c++流清晰地互操作。

使用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) + ".";

我建议你看一下这篇文章,以获得同样的观点。

如果你有很多格式化要做,我推荐boost::format。使用lexical_cast的简单孤立的东西,并使用stringstream,如果你有需求,使你需要他们(例如。自定义operator<<,不能使用boost等)。

说实话,snprintf真的很好。

c++的方法是std::stringstream

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

创建stringstream,使用'<<'操作符编写所需内容,然后使用成员函数.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();