1. 程式人生 > >istringstream、ostringstream、stringstream 類介紹 和 stringstream類 clear函數的真正用途

istringstream、ostringstream、stringstream 類介紹 和 stringstream類 clear函數的真正用途

輸入 emp ren 一個 str 三種 == 期望 數據轉換

istringstream、ostringstream、stringstream 類介紹 和 stringstream類 clear函數的真正用途

來源: http://blog.csdn.net/TQH_Candy/article/details/52494570

0、C++的輸入輸出分為三種:

(1)基於控制臺的I/O

技術分享圖片

(2)基於文件的I/O

技術分享圖片

(3)基於字符串的I/O

技術分享圖片

1、頭文件

  1. #include <sstream>

2、作用

istringstream類用於執行C++風格的字符串流的輸入操作。

ostringstream類用於執行C++風格的字符串流的輸出操作。

strstream類同時可以支持C++風格的串流的輸入輸出操作。

3、具體分析

istringstream類

描述:從流中提取數據,支持 >> 操作

這裏字符串可以包括多個單詞,單詞之間使用空格分開

  1. istringstream的構造函數原形:
  2. istringstream::istringstream(string str);

初始化:使用字符串進行初始化

  1. istringstream istr("1 56.7");
  2. istr.str("1 56.7");//把字符串"1 56.7"存入字符串流中

使用:我們可以使用分解點獲取不同的數據,完成 字符串 到 其他類型 的轉換

常用成員函數:

  1. str():使istringstream對象返回一個string字符串

舉例:把字符串類型的數據轉換為其他類型

  1. #include <iostream>
  2. #include <sstream>
  3. using namespace std;
  4. int main()
  5. {
  6. istringstream istr("1 56.7");
  7. cout<<istr.str()<<endl;//直接輸出字符串的數據 "1 56.7"
  8. string str = istr.str();//函數str()返回一個字符串
  9. cout<<str<<endl;
  10. int n;
  11. double d;
  12. //以空格為界,把istringstream中數據取出,應進行類型轉換
  13. istr>>n;//第一個數為整型數據,輸出1
  14. istr>>d;//第二個數位浮點數,輸出56.7
  15. //假設換下存儲類型
  16. istr>>d;//istringstream第一個數要自動變成浮點型,輸出仍為1
  17. istr>>n;//istringstream第二個數要自動變成整型,有數字的階段,輸出為56
  18. //測試輸出
  19. cout<<d<<endl;
  20. cout<<n<<endl;
  21. system("pause");
  22. return 1;
  23. }

舉例2:把一行字符串放入流中,單詞以空格隔開。之後把一個個單詞從流中依次讀取到字符串

  1. #include <iostream>
  2. #include <sstream>
  3. using namespace std;
  4. int main()
  5. {
  6. istringstream istr;
  7. string line,str;
  8. while (getline(cin,line))//從終端接收一行字符串,並放入字符串line中
  9. {
  10. istr.str(line);//把line中的字符串存入字符串流中
  11. while(istr >> str)//每次讀取一個單詞(以空格為界),存入str中
  12. {
  13. cout<<str<<endl;
  14. }
  15. }
  16. system("pause");
  17. return 1;
  18. }

輸入:123 34 45

輸出:

123 換行 34 換行 45

ostringstream類

描述:把其他類型的數據寫入流(往流中寫入數據),支持<<操作

  1. ostringstream的構造函數原形:
  2. ostringstream::ostringstream(string str);

初始化:使用字符串進行初始化

  1. ostringstream ostr("1234");
  2. ostr.str("1234");//把字符串"1234"存入字符串流中

舉例:

  1. #include <iostream>
  2. #include <sstream>
  3. using namespace std;
  4. int main()
  5. {
  6. //初始化輸出字符串流ostr
  7. ostringstream ostr("1234");
  8. cout<<ostr.str()<<endl;//輸出1234
  9. ostr.put(‘5‘);//字符4頂替了1的位置
  10. cout<<ostr.str()<<endl;//輸出5234
  11. ostr<<"67";//字符串67替代了23的位置,輸出5674
  12. string str = ostr.str();
  13. cout<<str<<endl;
  14. system("pause");
  15. return 1;
  16. }

stringstream類

描述:是對istringstream和ostringstream類的綜合,支持<<, >>操作符,可以進行字符串到其它類型的快速轉換

  1. stringstream的構造函數原形如下:
  2. stringstream::stringstream(string str);

初始化:使用字符串進行初始化

  1. stringstream str("1234");
  2. str.str("1234");//把字符串"1234"存入字符串流中

作用:

1、stringstream通常是用來做數據轉換的

2、將文件的所有數據一次性讀入內存

舉例1:基本數據類型變字符串

  1. /*基本數據類型變字符串*/
  2. #include <fstream>
  3. #include <iostream>
  4. #include <sstream>
  5. using namespace std;
  6. int main()
  7. {
  8. /*整型變字符串*/
  9. int n = 10;
  10. string str;
  11. stringstream stream;
  12. stream << n;
  13. stream >> str;
  14. cout<<str<<endl;
  15. stream.clear();//多次使用stringstream,要先清空下,不能使用stream.str("");否則下面輸出10
  16. /*char* 變 string*/
  17. char cStr[10] = "china";
  18. stream << cStr;
  19. stream >> str;
  20. cout<<str<<endl;
  21. system("pause");
  22. return 1;
  23. }

舉例2:字符串變基本數據類型

  1. /*字符串變基本數據類型*/
  2. #include <fstream>
  3. #include <iostream>
  4. #include <sstream>
  5. using namespace std;
  6. int main()
  7. {
  8. /*字符串 變 double*/
  9. double n;
  10. string str = "12.5";
  11. stringstream stream;
  12. stream << str;
  13. stream >> n;
  14. cout<<n<<endl;
  15. stream.clear();//多次使用stringstream,要先清空下,不能使用stream.str("");
  16. /*string 變 char* */
  17. string str1 = "china";
  18. char cStr[10];
  19. stream << str1;
  20. stream >> cStr;
  21. cout<<cStr<<endl;//輸出china
  22. system("pause");
  23. return 1;
  24. }
  1. 註意:
  1. #include <iostream>
  2. #include <sstream>
  3. using namespace std;
  4. int main(int argc,char *argv[])
  5. {
  6. std::stringstream stream;
  7. string str;
  8. while(1)
  9. {
  10. //clear(),這個名字讓很多人想當然地認為它會清除流的內容。
  11. //實際上,它並不清空任何內容,它只是重置了流的狀態標誌而已!
  12. stream.clear();
  13. // 去掉下面這行註釋,清空stringstream的緩沖,每次循環內存消耗將不再增加!
  14. //stream.str("");
  15. stream<<"sdfsdfdsfsadfsdafsdfsdgsdgsdgsadgdsgsdagasdgsdagsadgsdgsgdsagsadgs";
  16. stream>>str;
  17. //測試輸出每次循環,你的內存消耗增加了多少!
  18. cout<<"Size of stream = "<<stream.str().length()<<endl;
  19. system("PAUSE");
  20. }
  21. system("PAUSE");
  22. return EXIT_SUCCESS;
  23. }

由於stringstream構造函數會特別消耗內存,似乎不打算主動釋放內存(或許是為了提高效率),但如果你要在程序中用同一個流,反復讀寫大量的數據,將會造成大量的內存消耗,因些這時候,需要適時地清除一下緩沖 (用 stream.str("") )。

另外不要企圖用 stream.str().resize(0),或 stream.str().clear() 來清除緩沖,使用它們似乎可以讓stringstream的內存消耗不要增長得那麽快,但仍然不能達到清除stringstream緩沖的效果,內存的消耗還在緩慢的增長!,至於stream.flush(),則根本就起不到任何作用。

//=============================================

究竟什麽情況下需要用到clear

先來看一個stack overflow上的問題(http://stackoverflow.com/questions/35080342/using-two-string-streams-but-not-getting-same-result)

我將其簡化為以下代碼:

  1. int main() {
  2. string line = "1 2 3 4 5";
  3. stringstream s1(line);
  4. string temp;
  5. int toAdd;
  6. stringstream s2;
  7. while (s1 >> temp) {
  8. cout << "temp:" << temp << endl;
  9. s2 << temp;
  10. cout << "s2.str: " << s2.str() << endl;
  11. s2 >> toAdd;
  12. cout << "toAdd:" << toAdd << endl;
  13. s2.str("");
  14. }
  15. return 0;
  16. }

這個代碼的原意是要把line中的字符串形式的1 2 3 4 5一個一個地轉成int並輸出,所以我們期望的toAdd的輸出應該是1 2 3 4 5,但結果卻是 1 1 1 1 1, 如下圖

技術分享圖片 

可以從s2.str:這句輸出中看到, 只有第一次是正常地把temp輸入進s2,後面的都失敗了。

原因在於, s2在第一次調用完operator<<和operator>>後,來到了end-of-file的位置,此時stringstream會為其設置一個eofbit的標記位,標記其為已經到達eof。查文檔得知, 當stringstream設置了eofbit,任何讀取eof的操作都會失敗,同時,會設置failbit的標記位,標記為失敗狀態。所以後面的操作都失敗了,toAdd的值一直都是1。

Operations that attempt to read at the End-of-File fail, and thus both the eofbit and the failbit end up set. This function can be used to check whether the failure is due to reaching the End-of-File or to some other reason.

clear函數:

原型: void clear (iostate state = goodbit);

標誌位一共有4種, goodbit, eofbit, failbit, badbit

clear可以清除掉所有的error state

  1. int main() {
  2. string line = "1 2 3 4 5";
  3. stringstream s1(line);
  4. string temp;
  5. int toAdd;
  6. stringstream s2;
  7. while (s1 >> temp) {
  8. cout << "temp:" << temp << endl;
  9. s2 << temp;
  10. cout << "s2.str: " << s2.str() << endl;
  11. s2 >> toAdd;
  12. cout << "toAdd:" << toAdd << endl;
  13. s2.str("");
  14. if (s2.eof()) {
  15. s2.clear();
  16. cout << "s2.eof true" << endl;
  17. }
  18. }
  19. return 0;
  20. }

使用clear後, s2就可以正常地工作了,結果如下:  

技術分享圖片

參考網站:http://www.cplusplus.com/reference/sstream/stringstream/

     http://www.cplusplus.com/reference/ios/ios/clear/

istringstream、ostringstream、stringstream 類介紹 和 stringstream類 clear函數的真正用途