一、文件的輸入輸出
頭文件fstream定義了三個類型支持文件IO:ifstream從給定文件讀取數據、ofstream向一個給定文件寫入數據、fstream讀寫給定數據。這些類型與cin和cout的操作一樣,我們可以用IO操作符來讀寫文件,還可以用getline從一個ifstream讀取數據。
1、getline()函數
getline的函數原型為:
- istream& getline(istream& is, string& str, char delim);
- istream& getline(istream&& is, string& str, char delim);
- istream& getline(istream& is, string& str);
- istream& getline(istream&& is, string& str);
通常我們使用getline函數讀取一整行,該函數接受一個輸入流和一個string對象,函數從給定的輸入流中讀取內容,直到遇到換行符為止,然后將所讀的內容存入到個string對象中。
另外,當函數為istream& getline (istream& is, string& str, char delim);形式時,函數遇到delim也會停止。
2、使用文件流對象
當我們想要讀入一個文件時,可以定義一個文件流對象,並將對象與文件相關聯起來,每一個文件流類都定義了一個名為open的成員函數,完成一系列系統相關的操作。
open函數的原型為:
- void open (const char* filename, ios_base::openmode mode = ios_base::out);
- void open (const string& filename, ios_base::openmode mode = ios_base::out);
文件模式(mode)有一下幾種:
- ofstream outfile("E:\\out.txt", ofstream::app);
上述代碼打開out.txt文件,如果不存在,系統會創建此txt文件,並且定位到文件末尾。
打開的文件使用完成后一定要關閉,fstream提供了成員函數close()來完成此操作。
例:從hello.txt文件中讀取數據並寫入到out.txt中
- #include "stdafx.h"
- #include <vector>
- #include <string>
- #include <fstream>
- #include <iostream>
- using namespace std;
- int _tmain(int argc, _TCHAR* argv[])
- {
- ifstream myfile("E:\\hello.txt");
- ofstream outfile("E:\\out.txt", ofstream::app);
- string temp;
- if (!myfile.is_open())
- {
- cout << "未成功打開文件" << endl;
- }
- while(getline(myfile,temp))
- {
- outfile<<temp;
- }
- myfile.close();
- return 0;
- }
二、string流
string頭文件定義了三個類型來支持內存IO,istringstream向string寫入數據,ostringstream從string讀取數據,stringstream既可從string讀取數據也可向string寫數據,就像string是一個IO流一樣。
- #include "stdafx.h"
- #include <string>
- #include <sstream> //使用istringstream所需要的頭文件
- #include <iostream>
- using namespace std;
- int _tmain(int argc, _TCHAR* argv[])
- {
- string str = "I am a boy";
- istringstream is(str);
- string s;
- while (is >> s)
- {
- cout << s << endl;
- }
- return 0;
- }
輸出結果為:
I
am
a
boy
例:編寫程序,將來自一個文件中的行保存在一個vector<string>中,然后使用istringstream從vector讀取數據元素,每次讀取一個單詞。
- #include "stdafx.h"
- #include <vector>
- #include <string>
- #include <fstream>
- #include <sstream>
- #include <iostream>
- using namespace std;
- int _tmain(int argc, _TCHAR* argv[])
- {
- vector<string> vec;
- ifstream myfile("E:\\hello.txt");
- string temp;
- if (!myfile.is_open())
- {
- cout << "未成功打開文件" << endl;
- }
- while(getline(myfile,temp))
- {
- vec.push_back(temp);
- }
- for (auto it = vec.begin(); it != vec.end(); it++)
- {
- cout << *it << endl;
- }
- cout << "-----------------使用istringstream------------------------" << endl;
- for (auto it = vec.begin(); it != vec.end(); it++)
- {
- istringstream record(*it);
- string s;
- while (record >> s)
- cout << s << endl;
- }
- return 0;
- }
運行結果如圖所示:
//下述論述轉自www.cndev-lab.com ,程序作者:管寧
- #i nclude <iostream>
- #i nclude <sstream>
- using namespace std;
- int main()
- {
- istringstream istr;
- istr.str("1 56.7",);
- //上述兩個過程可以簡單寫成 istringstream istr("1 56.7");
- cout << istr.str()<<endl;
- int a;
- float b;
- istr>>a;
- cout<<a<<endl;
- istr>>b;
- cout<<b<<endl;
- system("pause");
- }
上例中,構造字符串流的時候,空格會成為字符串參數的內部分界,例子中對a,b對象的輸入"賦值"操作證明了這一點,字符串的空格成為了整型數據與浮點型數據的分解點,利用分界獲取的方法我們事實上完成了字符串到整型對象與浮點型對象的拆分轉換過程。
str()成員函數的使用可以讓istringstream對象返回一個string字符串(例如本例中的輸出操作(cout<<istr.str();)。
ostringstream同樣是由一個string對象構造而來,ostringstream類向一個string插入字符。
ostringstream的構造函數原形如下:
- ostringstream::ostringstream(string str);
//下述論述轉自www.cndev-lab.com ,程序作者:管寧
- #i nclude <iostream>
- #i nclude <sstream>
- #i nclude <string>
- using namespace std;
- int main()
- {
- ostringstream ostr;
- //ostr.str("abc");//如果構造的時候設置了字符串參數,那么增長操作的時候不會從結 尾開始增加,而是修改原有數據,超出的部分增長
- ostr.put('d');
- ostr.put('e');
- ostr<<"fg";
- string gstr = ostr.str();
- cout<<gstr;
- system("pause");
- }
在上例代碼中,我們通過put()或者左移操作符可以不斷向ostr插入單個字符或者是字符串,通過str()函數返回增長過后的完整字符串數據,但值 得注意的一點是,當構造的時候對象內已經存在字符串數據的時候,那么增長操作的時候不會從結尾開始增加,而是修改原有數據,超出的部分增長。