C++ 簡單讀寫文本文件、統計文件的行數、讀取文件數據到數組
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() 到達文件尾
實例:
一、寫入文件
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
ofstream in;
in.open("com.txt",ios::trunc); //ios::trunc表示在打開文件前將文件清空,由於是寫入,文件不存在則創建
int i;
char a='a';
for(i=1;i<=26;i++)//將26個數字及英文字母寫入文件
{
if(i<10)
{
in<<"0"<<i<<"\t"<<a<<"\n";
a++;
}
else
{
in<<i<<"\t"<<a<<"\n";
a++;
}
}
in.close();//關閉文件
}
打開com.txt,效果如下:
二、讀取文件
上面僅僅是將文本寫入文件,並沒有讀取出來。
以下為讀取文件的一種方法:將文件每行內容存儲到字符串中,再輸出字符串
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
char buffer[256];
fstream out;
out.open("com.txt",ios::in);
cout<<"com.txt"<<" 的內容如下:"<<endl;
while(!out.eof())
{
out.getline(buffer,256,'\n');//getline(char *,int,char) 表示該行字符達到256個或遇到換行就結束
cout<<buffer<<endl;
}
out.close();
cin.get();//cin.get() 是用來讀取回車鍵的,如果沒這一行,輸出的結果一閃就消失了
}
逐個字符的讀取文件:
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
fstream in;
char c;
in.open("comn.txt",ios::in);
while(!in.eof())
{
in>>c;
cout<<c;
}
in.close();
cin.get();
}
這個方法讀取的文件,所有字符都一起顯示,不會分行。這里字母z顯示兩次,是正常的,因為在輸出文件最后一個字母z之后,又輸出了一次(可以仔細考慮程序代碼)。
讀取文件某一行內容:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int CountLines(char *filename)
{
ifstream ReadFile;
int n=0;
string tmp;
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在
{
while(getline(ReadFile,tmp))
{
n++;
}
return n;
}
ReadFile.close();
}
string ReadLine(char *filename,int line)
{
int lines,i=0;
string temp;
fstream file;
file.open(filename,ios::in);
lines=CountLines(filename);
if(line<=0)
{
return "Error 1: 行數錯誤,不能為0或負數。";
}
if(file.fail())
{
return "Error 2: 文件不存在。";
}
if(line>lines)
{
return "Error 3: 行數超出文件長度。";
}
while(getline(file,temp)&&i<line-1)
{
i++;
}
file.close();
return temp;
}
void main()
{
int l;
char filename[256];
cout<<"請輸入文件名:"<<endl;
cin>>filename;
cout<<"\n請輸入要讀取的行數:"<<endl;
cin>>l;
cout<<ReadLine(filename,l);
cin.get();
cin.get();
}
很顯然,根據以上程序,利用循環,可以逐行讀取整個文件內容。
三、統計文件的行數
#include <iostream>
#include <fstream>
using namespace std;
int CountLines(char *filename)
{
ifstream ReadFile;
int n=0;
char line[512];
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在
{
while(!ReadFile.eof())
{
ReadFile.getline(line,512,'\n');
n++;
}
return n;
}
ReadFile.close();
}
void main()
{
cout<<"comn.txt的行數為: "<<CountLines("comn.txt")<<endl;
cin.get();
}
以上程序的設計思路沒有問題,但在實際操作的時候會發現統計出的行數與實際不符,原因在於ReadFile.getline(line,512,'\n')這一句:當一行字符超過512或遇到回車之后,行數自動加1.如果換行符在新的一行,返回的結果會比實際多1;如果不在新的一行,返回結果與實際相符。可以修改如下:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int CountLines(char *filename)
{
ifstream ReadFile;
int n=0;
char line[512];
string temp;
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在
{
while(getline(ReadFile,temp))
{
n++;
}
return n;
}
ReadFile.close();
}
void main()
{
cout<<"comn.txt的行數為: "<<CountLines("comn.txt")<<endl;
cin.get();
}
四、讀取文件數據到數組
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int CountLines(char *filename)//獲取文件的行數
{
ifstream ReadFile;
int n=0;
string temp;
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在,返回文件行數
{
while(getline(ReadFile,temp))
{
n++;
}
return n;
}
ReadFile.close();
}
void main()
{
ifstream file;
int LINES;
char filename[512];
cout<<"請輸入要打開的文件名:"<<endl;
cin>>filename;
file.open(filename,ios::in);
if(file.fail())
{
cout<<"文件不存在."<<endl;
file.close();
cin.get();
cin.get();
}
else//文件存在
{
LINES=CountLines(filename);
int *tc=new int[LINES];
char *t=new char[LINES];
int i=0;
while(!file.eof()) //讀取數據到數組
{
file>>tc[i];
file>>t[i];
i++;
}
file.close(); //關閉文件
for(i=0;i<LINES;i++)//輸出數組內容
cout<<tc[i]<<"\t"<<t[i]<<endl;
cin.get();
cin.get();
}
}
C++ 簡單讀寫文本文件、統計文件的行數、讀取文件數據到數組
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() 到達文件尾
實例:
一、寫入文件
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
ofstream in;
in.open("com.txt",ios::trunc); //ios::trunc表示在打開文件前將文件清空,由於是寫入,文件不存在則創建
int i;
char a='a';
for(i=1;i<=26;i++)//將26個數字及英文字母寫入文件
{
if(i<10)
{
in<<"0"<<i<<"\t"<<a<<"\n";
a++;
}
else
{
in<<i<<"\t"<<a<<"\n";
a++;
}
}
in.close();//關閉文件
}
打開com.txt,效果如下:
二、讀取文件
上面僅僅是將文本寫入文件,並沒有讀取出來。
以下為讀取文件的一種方法:將文件每行內容存儲到字符串中,再輸出字符串
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
char buffer[256];
fstream out;
out.open("com.txt",ios::in);
cout<<"com.txt"<<" 的內容如下:"<<endl;
while(!out.eof())
{
out.getline(buffer,256,'\n');//getline(char *,int,char) 表示該行字符達到256個或遇到換行就結束
cout<<buffer<<endl;
}
out.close();
cin.get();//cin.get() 是用來讀取回車鍵的,如果沒這一行,輸出的結果一閃就消失了
}
逐個字符的讀取文件:
#include <iostream>
#include <fstream>
using namespace std;
void main()
{
fstream in;
char c;
in.open("comn.txt",ios::in);
while(!in.eof())
{
in>>c;
cout<<c;
}
in.close();
cin.get();
}
這個方法讀取的文件,所有字符都一起顯示,不會分行。這里字母z顯示兩次,是正常的,因為在輸出文件最后一個字母z之后,又輸出了一次(可以仔細考慮程序代碼)。
讀取文件某一行內容:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int CountLines(char *filename)
{
ifstream ReadFile;
int n=0;
string tmp;
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在
{
while(getline(ReadFile,tmp))
{
n++;
}
return n;
}
ReadFile.close();
}
string ReadLine(char *filename,int line)
{
int lines,i=0;
string temp;
fstream file;
file.open(filename,ios::in);
lines=CountLines(filename);
if(line<=0)
{
return "Error 1: 行數錯誤,不能為0或負數。";
}
if(file.fail())
{
return "Error 2: 文件不存在。";
}
if(line>lines)
{
return "Error 3: 行數超出文件長度。";
}
while(getline(file,temp)&&i<line-1)
{
i++;
}
file.close();
return temp;
}
void main()
{
int l;
char filename[256];
cout<<"請輸入文件名:"<<endl;
cin>>filename;
cout<<"\n請輸入要讀取的行數:"<<endl;
cin>>l;
cout<<ReadLine(filename,l);
cin.get();
cin.get();
}
很顯然,根據以上程序,利用循環,可以逐行讀取整個文件內容。
三、統計文件的行數
#include <iostream>
#include <fstream>
using namespace std;
int CountLines(char *filename)
{
ifstream ReadFile;
int n=0;
char line[512];
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在
{
while(!ReadFile.eof())
{
ReadFile.getline(line,512,'\n');
n++;
}
return n;
}
ReadFile.close();
}
void main()
{
cout<<"comn.txt的行數為: "<<CountLines("comn.txt")<<endl;
cin.get();
}
以上程序的設計思路沒有問題,但在實際操作的時候會發現統計出的行數與實際不符,原因在於ReadFile.getline(line,512,'\n')這一句:當一行字符超過512或遇到回車之后,行數自動加1.如果換行符在新的一行,返回的結果會比實際多1;如果不在新的一行,返回結果與實際相符。可以修改如下:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int CountLines(char *filename)
{
ifstream ReadFile;
int n=0;
char line[512];
string temp;
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在
{
while(getline(ReadFile,temp))
{
n++;
}
return n;
}
ReadFile.close();
}
void main()
{
cout<<"comn.txt的行數為: "<<CountLines("comn.txt")<<endl;
cin.get();
}
四、讀取文件數據到數組
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int CountLines(char *filename)//獲取文件的行數
{
ifstream ReadFile;
int n=0;
string temp;
ReadFile.open(filename,ios::in);//ios::in 表示以只讀的方式讀取文件
if(ReadFile.fail())//文件打開失敗:返回0
{
return 0;
}
else//文件存在,返回文件行數
{
while(getline(ReadFile,temp))
{
n++;
}
return n;
}
ReadFile.close();
}
void main()
{
ifstream file;
int LINES;
char filename[512];
cout<<"請輸入要打開的文件名:"<<endl;
cin>>filename;
file.open(filename,ios::in);
if(file.fail())
{
cout<<"文件不存在."<<endl;
file.close();
cin.get();
cin.get();
}
else//文件存在
{
LINES=CountLines(filename);
int *tc=new int[LINES];
char *t=new char[LINES];
int i=0;
while(!file.eof()) //讀取數據到數組
{
file>>tc[i];
file>>t[i];
i++;
}
file.close(); //關閉文件
for(i=0;i<LINES;i++)//輸出數組內容
cout<<tc[i]<<"\t"<<t[i]<<endl;
cin.get();
cin.get();
}
}
原文地址:ifstream用法作者:yu_ynan
ofstream 和ifstream的具體用法
2008-03-30 23:38:轉自:http://hi.baidu.com/sibeichen055/blog/item/e81aca3398d807fc1b4cff78.html
這個小知識點迷糊了很久了,前段時間始終沒有搞清楚,今天又拿過來看的時候好象明白了點...... 今天將ifstream 與ofstream的用法歸納一下 ofstream是從內存到硬盤,ifstream是從硬盤到內存,其實所謂的流緩沖就是內存空間; 在C 中,有一個stream這個類,所有的I/O都以這個“流”類為基礎的,包括我們要認識的文件I/O,stream這個類有兩個重要的運算符: 1、插入器(<<) 2、析取器(>>) 在C 中,對文件的操作是通過stream的子類fstream(file stream)來實現的,所以,要用這種方式操作文件,就必須加入頭文件fstream.h。下面就把此類的文件操作過程一一道來。 一、打開文件 void open(const char* filename,int mode,int access); 參數: filename: 要打開的文件名 ios::app: 以追加的方式打開文件 打開文件的屬性取值是: 0:普通文件,打開訪問 例如:以二進制輸入方式打開文件c:config.sys 如果open函數只有文件名一個參數,則是以讀/寫普通文件打開,即: 另外,fstream還有和open()一樣的構造函數,對於上例,在定義的時侯就可以打開文件了: 特別提出的是,fstream有兩個子類:ifstream(input file stream)和ofstream(outpu file stream),ifstream默認以輸入方式打開文件,而ofstream默認以輸出方式打開文件。 所以,在實際應用中,根據需要的不同,選擇不同的類來定義:如果想以輸入方式打開,就用ifstream來定義;如果想以輸出方式打開,就用ofstream來定義;如果想以輸入/輸出方式來打開,就用fstream來定義。 二、關閉文件 三、讀寫文件 1、文本文件的讀寫 file2<<"I Love You";//向文件寫入字符串"I Love You" 這種方式還有一種簡單的格式化能力,比如可以指定輸出為16進制等等,具體的格式有以下一些 操縱符 功能 輸入/輸出 比如要把123當作十六進制輸出:file1<<hex<<123;要把3.1415926以5位精度輸出:file1<<setpxecision(5)<<3.1415926。 2、二進制文件的讀寫 ②get() 一種就是和put()對應的形式:ifstream &get(char &ch);功能是從流中讀取一個字符,結果保存在引用ch中,如果到文件尾,返回空字符。如file2.get(x);表示從文件中讀取一個字符,並把讀取的字符保存在x中。 另一種重載形式的原型是: int get();這種形式是從流中返回一個字符,如果到達文件尾,返回EOF,如x=file2.get();和上例功能是一樣的。 還有一種形式的原型是:ifstream &get(char *buf,int num,char delim='n');這種形式把字符讀入由 buf 指向的數組,直到讀入了 num 個字符或遇到了由 delim 指定的字符,如果沒使用 delim 這個參數,將使用缺省值換行符'n'。例如: file2.get(str1,127,'A'); //從文件中讀取字符到字符串str1,當遇到字符'A'或讀取了127個字符時終止。 ③讀寫數據塊 read(unsigned char *buf,int num); read()從文件中讀取 num 個字符到 buf 指向的緩存中,如果在還未讀入 num 個字符時就到了文件尾,可以用成員函數 int gcount();來取得實際讀取的字符數;而 write() 從buf 指向的緩存寫 num 個字符到文件中,值得注意的是緩存的類型是 unsigned char *,有時可能需要類型轉換。 例: unsigned char str1[]="I Love You"; 四、檢測EOF 例: if(in.eof()) ShowMessage("已經到達文件尾!"); 五、文件定位 istream &seekg(streamoff offset,seek_dir origin); streamoff定義於 iostream.h 中,定義有偏移量 offset 所能取得的最大值,seek_dir 表示移動的基准位置,是一個有以下值的枚舉: ios::beg: 文件開頭 這兩個函數一般用於二進制文件,因為文本文件會因為系統對字符的解釋而可能與預想的值不同。例: file1.seekg(1234,ios::cur); //把文件的讀指針從當前位置向后移1234個字節
|
ofstream ifstream 文件操作
////////////////////////////////////////////////////
2009-11-15 11:18轉自http://hi.baidu.com/bigbigrabbit/blog/item/9122d1a823337ff61e17a2ed.html
ifstream和ofstream是fstream.h頭文件中的類,所以在使用這兩個類的時候一定要加入#include <fstream.h>。總體說一下:ifstream的作用是從文件中讀出,ofstream是寫入向文件寫入數據,他們的構造函數是:ofstream::ofstream(const char *filename,int mode = ios::out,int openprot = filebuf::openprot);ifstream與此類似。Filename,是文件名稱,用“”括起來,如果是本目錄下則只需寫上文件名字,不需要寫文件路徑;mode是打開方式,一般情況我們默認即可;openprot是屬性,一般也是默認。 下面用三個例子說明: 一,寫入數字 ofstream writefile("3.txt"); //定義對象,往文件寫數據 if (writefile) //檢查文件是否打開,如果打開則寫數據 { writefile<<"0 1 2 3 4 5 6 7 8 9"; }
ifstream readfile("3.txt"); //定義對象,讀取數據 int date; for (int j=0; j<=9; j ) { readfile>>date; cout<<date<<endl; } 這里面用到了兩個重要的操作符:<<和>>。<<是向文件中寫入,>>從文件中讀取。當然,寫入操作和讀取操作不能放在一起,如果放在一起就會讀取不成功。 二,寫入字符 ofstream writefile("3.txt"); char ch[]="woaini"; for (int i=0; i<strlen(ch); i ) { writefile.put(ch[i]); }
ifstream readfile("3.txt"); char date; while (readfile.get(date)) //get之所以可以這樣用,因為讀到文件末尾就會返回false。 { cout<<date<<endl; } 這里用到兩個方法:put和get。Put是寫入單個字符,get是讀取單個字符。當然上面的寫入操作可以用<<進行,writefile<<”woaini”; 三,整行讀寫 ifstream readfile("1.txt"); ofstream writefile("2.txt"); const int len=200; char str[len]; while (readfile.getline(str,len)) { writefile<<str<<'n'; } 這個例子中,1.txt是一個已有文檔,里面寫滿了文字,此程序是把1.txt中的內容寫到2.txt中並且保存1.txt中格式不變。 整行讀寫中用到一個重要函數:getline,MSDN中的函數原型istream& getline(char* pch, int nCount, char delim='n');pch是字符數組,用來裝讀取的數據的;nCount是重要參數,指示一次讀取長度;delim是以什么字符結尾,默認是’n’;也可是自己指定。 例子中有兩個重要點,一是,len的選取,如果選取過於小,兩個n之間的長度大於len,就會讀取亂碼,所以len盡量要大。二是,writefile<<str<<'n';中'n'是必須的,這是用來保證格式相同的。 |