2011-05-01 146 views
4

我有一些C++代碼,當解析某個文件頭失敗時,需要生成一條錯誤消息。在這種情況下,我需要確保標題中的某個4字節字段爲「OggS」,如果不是,則返回錯誤消息,如「無效capture_pattern:'FooB';期待'OggS'」。我的代碼看起來像這樣:什麼是替代snprintf(3)的C++習慣用法?

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)風格的格式,所以請隨時提出任何有用的建議。

+0

另外請注意:您在'sizeof(capture_pattern)'中忘了')'。 – Lstor 2011-05-01 09:05:05

+1

只是一個筆記...自從你接受了一個涉及 2015-12-07 08:26:47

+0

@tea的回答後,刪除這個'只是一個便條'注意事項只是一個註釋...我刪除了'只是一個便條'註釋以迴應你的'只是一個註釋'註釋。 ;-P – 2015-12-08 08:56:37

回答

5

您可以使用stringstreamostringstream從C++標準庫。如果進一步的數據流不會被用來從數據中讀取數據(例如它的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

這是C++標準庫,而不是STL。 – 2011-05-01 09:08:51

+0

@Tomalak Geret'kal:感謝您的糾正。答案已更正。 – beduin 2011-05-01 09:13:25

+0

爲什麼'std :: stringstream',而不是'std :: ostringstream'? – 2011-05-01 09:19:00

1

這樣做的C++方法是std::stringstream

std::stringstream err; 
err << "Failed to read " << sizeof(capture_pattern) 
         << " bytes from fd " << fd << std::endl; 
return err.str(); 
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作爲簡單的隔離事物,如果您有要求使用它們(例如,自定義operator<<,不能使用boost等),請使用stringstream

說實話,snprintf真的很好。

0

您創建一個字符串流,寫下你想用的是什麼「< <」操作,然後拿到串出流與成員函數名爲.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(); 
1

就像一張紙條,請不要建議爲實際讀數替換 - 有,我想使用C標準庫I/O這裏的理由。 :)

你真的不能索要「習慣」的方式做一些C++,然後說:「但我想堅持到C標準庫...

反正你有三個選項。我不相信任何人是慣用(因爲這將意味着某種共識,這個作爲最好方式):與您已經使用

  • 的C API的

    • 棒使用的C++ std::stringstream,這是部分的標準庫的輸入輸出流部
    • 使用Boost.Format庫

    後者的優點是它依賴於第三方的lib下行rary,但其優點是它以類似安全和可擴展的方式爲您提供類似於語法的好處,它與C++流乾淨地交互操作。

  • +0

    'strncmp'絕對很好,而且「慣用」:找到一個更好的方法來做到這一點,看看我的意思。 – 2011-05-01 09:23:23

    +0

    呃? C字符串比較函數如何成爲C++中字符串格式化的慣用解決方案? – jalf 2011-05-01 10:00:08

    +0

    @jalf:因爲這是最簡單的工作。 – 2011-05-01 10:24:11

    相關問題