C++讀寫TXT文件中的string或者int型數據以及string流的用法


    對文件的讀寫操作是我們在做項目時經常用到的,在網上看了很多博客,結合自身的項目經驗總結了一下,因此寫了這篇博客,有些地方可能直接從別的博客中復制過來,但是都會注明出處。

 

  一、文件的輸入輸出

      fstream提供了三個類,用來實現c++對文件的操作。(文件的創建、讀、寫)。

      ifstream -- 從已有的文件讀入

      ofstream -- 向文件寫內容

      fstream - 打開文件供讀寫

     文件打開模式:

     ios::in             只讀

     ios::out            只寫

     ios::app            從文件末尾開始寫,防止丟失文件中原來就有的內容

     ios::binary         二進制模式

     ios::nocreate       打開一個文件時,如果文件不存在,不創建文件

     ios::noreplace      打開一個文件時,如果文件不存在,創建該文件

     ios::trunc          打開一個文件,然后清空內容

     ios::ate            打開一個文件時,將位置移動到文件尾

     文件指針位置在c++中的用法:

     ios::beg   文件頭

     ios::end   文件尾

     ios::cur   當前位置

     例子:

     file.seekg(0,ios::beg);   //讓文件指針定位到文件開頭 

     file.seekg(0,ios::end);   //讓文件指針定位到文件末尾 

     file.seekg(10,ios::cur);   //讓文件指針從當前位置向文件末方向移動10個字節 

     file.seekg(-10,ios::cur);   //讓文件指針從當前位置向文件開始方向移動10個字節 

     file.seekg(10,ios::beg);   //讓文件指針定位到離文件開頭10個字節的位置

    注意:移動的單位是字節,而不是行

    常用的錯誤判斷方法:

    good()   如果文件打開成功

    bad()   打開文件時發生錯誤

    eof()    到達文件尾

    以上內容參考自:http://www.cnblogs.com/helinsen/archive/2012/07/26/2609251.html

    下面給出一個例子,讀取hello.txt文件中的字符串,寫入out.txt中:

  

#include <vector>  
#include <string>  
#include <fstream>  
#include <iostream>  

using namespace std;  

int main()  
{  
    ifstream myfile("G:\\C++ project\\Read\\hello.txt");  
    ofstream outfile("G:\\C++ project\\Read\\out.txt", ios::app);  
    string temp;  
    if (!myfile.is_open())  
    {  
        cout << "未成功打開文件" << endl;  
    }  
    while(getline(myfile,temp))  
    {  
        outfile << temp;  
		outfile << endl;
    }  
    myfile.close();  
	outfile.close();
    return 0;  
}  

  hello.txt文件中的內容為:

    上式程序執行3遍后,out.txt文件中的內容為:

 

   上述代碼讀取的是string類型的數據,那么對於int型數據該怎么辦呢,其實道理差不多,下面舉例說明:

#include<iostream>
#include <string>
#include <vector>
#include <fstream>  //文件流庫函數

using namespace std;

int cost[10][10];

int main()
{	
	int v, w, weight;
	ifstream infile;   //輸入流
	ofstream outfile;   //輸出流

	infile.open("G:\\C++ project\\Read\\data.txt", ios::in);  
	if(!infile.is_open ())
		cout << "Open file failure" << endl;
	while (!infile.eof())            // 若未到文件結束一直循環 
	{
		infile >> v >> w >> weight;
		cost[v][w] = weight;
		cost[w][v] = weight;	             
	}
	infile.close();   //關閉文件
	
	outfile.open("G:\\C++ project\\Read\\result.txt", ios::app);   //每次寫都定位的文件結尾,不會丟失原來的內容,用out則會丟失原來的內容
	if(!outfile.is_open ())
		cout << "Open file failure" << endl;
	for (int i = 0; i != 10; ++i)
	{
		for (int j = 0; j != 10; ++j)
		{
			outfile << i << "\t" << j << "\t" << cost[i][j] << endl;  //在result.txt中寫入結果
		}

	}
	outfile.close();

	return 0;
	while (1);
}

  上述代碼的功能是讀取data.txt文件的數據,注意,此時要求data.txt文件中的數據是三個一行,每個數據用空格隔開,之所以這樣做,是因為在許多項目中,比如某為的算法比賽中,根據圖的數據構建圖的鄰接矩陣或者鄰接表時,數據都是這樣安排的,在上面的代碼中v和w代表頂點標號,weight代表邊<v,w>的權值,上述代碼的功能就是構建由data.txt文件描述的圖的鄰近矩陣。

     data.txt文件的數據如下:

  程序運行后,result.txt文件的內容如下:

  

   注意:數據太長,只給出了一部分。

 

   事實上,要求data.txt文件中的數據都是如此排列的要求有點高,如果data.txt文件中有的行有兩個數據,有的行有三個數據,有的行有4個數據,上述方法就行不通了,其實改一下上面的代碼就可以了,重要的是你要明白什么時候讀取的那一行有幾個數據,下面舉例說明:

   假設data.txt文件中的數據如下:

第一行的數據表示,每行有三個數據的有5行,且在前面,每行有兩個的數據的有兩行,在后面,除第一行外,后面的才是正真的數據,因此讀取這些數據的代碼如下:

#include<iostream>
#include <string>
#include <vector>
#include <fstream>  //文件流庫函數

using namespace std;

int cost[10][10];

int main()
{	
	int Num_3,Num_2;
	int v, w, weight;
	ifstream infile;   //輸入流
	ofstream outfile;   //輸出流

	infile.open("G:\\C++ project\\Read\\data.txt", ios::in);  
	if(!infile.is_open ())
		cout << "Open file failure" << endl;

	infile >> Num_3 >>Num_2 ;   //先讀取第一行

	while (Num_3 != 0)            // 讀取3個數據的
	{
		infile >> v >> w >> weight;
		cost[v][w] = weight;
		cost[w][v] = weight;	
		Num_3--;
	}

	while (Num_2 != 0)            // 讀取3個數據的
	{
		infile >> v >> w;
		cost[v][w] = 100;
		cost[w][v] = 100;	
		Num_2--;
	}

	infile.close();   //關閉文件
	
	outfile.open("G:\\C++ project\\Read\\result.txt", ios::out);   //每次寫都定位的文件結尾,不會丟失原來的內容,用out則會丟失原來的內容
	if(!outfile.is_open ())
		cout << "Open file failure" << endl;
	for (int i = 0; i != 10; ++i)
	{
		for (int j = 0; j != 10; ++j)
		{
			outfile << i << "\t" << j << "\t" << cost[i][j] << endl;  //在result.txt中寫入結果
		}

	}
	outfile.close();

	return 0;
	while (1);
}

  為方便檢驗,我們把那些沒有指明權值的邊(即對應data.txt文件中那些每行只有兩個數據的)的權值設為100,上述代碼執行結果如下:

 結果顯示,讀取正確。

 

   注意:上面的代碼之所以運行成立,是因為每行之間空幾行好像並沒有影響,比如上面的data.txt中,第一行與第二行之間空1行或者2行都沒有關系。

 

二、string

   以下內容參考自:http://blog.csdn.net/xujian_2014/article/details/42679525

    string頭文件定義了三個類型來支持內存IO,istringstream向string讀取數據,ostringstream從string寫數據,stringstream既可從string讀取數據也可向string寫數據,就像string是一個IO流一樣。

  1、istringstream的用法,例子如下:

#include <string>  
#include <sstream>    //使用istringstream所需要的頭文件  
#include <iostream>  
using namespace std;  
int main()  
{  
    string str = "Hello word! I am Lee";  
    istringstream is(str);    //將is綁定到str
    string s;  
    while (is >> s)  
    {  
        cout << s << endl;  
    }  
    return 0;  
}

  上述代碼運行結果如下:

這相當於把一個句子拆分成單詞,聯系到前文提到的從文件中讀取string的方法,如果讀取到的string對象為一個句子,包含很多單詞,那么我們就可以運用這種方法把string對象拆分開來。

  

   2、ostringstream的用法

        ostringstream同樣是由一個string對象構造而來,ostringstream類向一個string插入字符。 

#include <string>  
#include <sstream>    //使用ostringstream所需要的頭文件  
#include <iostream>   
using namespace std;   
int main()     
{   
    ostringstream ostr;   
   // ostr.str("abc");//如果構造的時候設置了字符串參數,那么增長操作的時候不會從結尾開始增加,而是修改原有數據,超出的部分增長   
    ostr.put('d');   
    ostr.put('e');   
    ostr<<"fg";     
    string gstr = ostr.str();   
    cout<<gstr << endl;  
	return 0;
}  

  運行結果如下:

      在上例代碼中,我們通過put()或者左移操作符可以不斷向ostr插入單個字符或者是字符串,通過str()函數返回增長過后的完整字符串數據,但值 得注意的一點是,當構造的時候對象內已經存在字符串數據的時候,那么增長操作的時候不會從結尾開始增加,而是修改原有數據,超出的部分增長。

   夜深了,,,

 

  廣州的天氣總是邊的如此的快,又下雨了,,,


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM