2016-07-06 62 views
3

什麼是從std::basic_istream中提取特定數量字符並將其存儲在std::string中的好方法?從std :: basic_istream複製特定數量的字符到std :: string

在下面的程序中,我使用char[]最終獲得result,但我想,以避免POD類型和保證的東西更安全,更易於維護:

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

int main() 
{ 
    std::stringstream inss{std::string{R"(some/path/to/a/file/is/stored/in/50/chars   Other data starts here.)"}}; 
    char arr[50]{}; 
    if (!inss.read(arr,50)) 
     throw std::runtime_error("Could not read enough characters.\n"); 

    //std::string result{arr}; // Will probably copy past the end of arr 
    std::string result{arr,arr+50}; 

    std::cout << "Path is: " << result << '\n'; 
    std::cout << "stringstream still has: " << inss.str() << '\n'; 

    return 0; 
} 

替代方案:

  • 轉換整個流向前一個字符串:std::string{inss.c_str()}
    • 這似乎是浪費,因爲它無線ld製作整個流的副本。
  • 寫模板函數接受char[]
    • 這仍然使用中間POD陣列。
  • 使用std::basic_istream::get在循環中讀取所需的字符數與std::basic_string::push_back
    • 循環似乎有點笨拙起來,但它避免了陣列。
+0

可能的重複:[如何從字符串流中取出字符而不進行復制?](http://stackoverflow.com/questions/28663075/how-to-get-characters-out -of-stringstream-without-copy) – NathanOliver

+0

你保證文件名是50個字符或更少? –

+0

@QPaysTaxes文件格式具有分配給文件名的前50個字符。所以只要文件格式保持不變,就可以保證。風險在於文件格式發生變化,然後代碼必須更改。 – wally

回答

2

就直接讀入result字符串。

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

int main() 
{ 
    std::stringstream inss{std::string{R"(some/path/to/a/file/is/stored/in/50/chars   Other data starts here.)"}}; 
    std::string result(50, '\0'); 

    if (!inss.read(&result[0], result.size())) 
     throw std::runtime_error("Could not read enough characters.\n"); 

    std::cout << "Path is: " << result << '\n'; 
    std::cout << "stringstream still has: " << inss.str() << '\n'; 

    return 0; 
} 

由於C++ 11,關於std::stringfrom cppreference)的存儲器佈局以下保證。

一個basic_string的元素被存儲連續,即,用於一basic_string s&*(s.begin() + n) == &*s.begin() + n任何n[0, s.size()),或等價地,一個指針s[0]可以傳遞給該期望的指針的第一個元素的功能的CharT[]陣列。 (從C++ 11開始)

+2

@jaggedSpire這就是說,如果你在'size'函數返回的值相等時訪問'pos'。在這個例子中,'0'用於'pos',而'50'由'size'返回,並且沒有未定義的行爲。 –

+0

這正是我正在尋找的答案。現在看起來如此明顯...... :) – wally

+0

@JamesAdkison是的,在我發佈之後發現。抱歉。 – jaggedSpire

相關問題