一、檔案的輸入輸出
頭檔案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流一樣。
1、istringstream的用法
#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();)。
2、ostringstream的用法
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()函數傳回增長過後的完整字元串資料,但值 得注意的一點是,當構造的時候對象内已經存在字元串資料的時候,那麼增長操作的時候不會從結尾開始增加,而是修改原有資料,超出的部分增長。