1. 程式人生 > 實用技巧 >c++輸入檔案流ifstream用法詳解

c++輸入檔案流ifstream用法詳解

轉載:https://blog.csdn.net/sinat_36219858/article/details/80369255

輸入流的繼承關係:

ios_base <- ios <- istream <- ifstream

這裡寫圖片描述

C++ 使用標準庫類來處理面向流的輸入和輸出:

iostream 處理控制檯 IO
fstream 處理命名檔案 IO
stringstream 完成記憶體 string 的IO
每個IO 物件都維護一組條件狀態 flags (eofbit, failbit and badbit),用來指出此物件上是否可以進行 IO 操作。如果遇到錯誤—例如輸入流遇到了檔案末尾,則物件的狀態變為是失效,所有的後續輸入操作都不能執行,直到錯誤糾正。

標頭檔案 包含的多個檔案流類,這裡列出常用的4個:

ifstream Input file stream class (class )連結
ofstream Output file stream (class )連結
fstream Input/output file stream class (class )連結
filebuf File stream buffer (class )連結
成員函式

Public member functions

1, (constructor)

第一種不繫結檔案,後續用open() 繫結。
第二種繫結檔案 filename ,讀取模式預設引數為 ios_base::in可以省略。

default (1) ifstream();
initialization (2)
explicit ifstream (const char* filename, ios_base::openmode mode = ios_base::in);
explicit ifstream (const string& filename, ios_base::openmode mode = ios_base::in);

2,ifstream::open

開啟檔案filename,模式預設 ios_base::in

void open (const char* filename, ios_base::openmode mode = ios_base::in);
void open (const string& filename, ios_base::openmode mode = ios_base::in);

函式引數:

filename 要開啟檔案的檔名
mode 開啟檔案的方式
member constant stands for access
in input File 讀的方式開啟檔案
out output 寫的方式開啟檔案
binary binary 二進位制方式開啟
ate at end 開啟的時候定位到檔案末尾
app append 所有操作都定位到檔案末尾
trunc truncate 丟棄開啟前檔案存在的內容
3,ifstream:: is_open

bool is_open() const;

檔案流物件與檔案繫結,返回 true ,否則 false 。

4,ifstream:: close

void close(); //關閉檔案流

5,ifstream:: rdbuf

filebuf* rdbuf() const;

返回一個 filebuf 物件指標,(The pointer to the internal filebuf object.)

6,ifstream:: operator =

copy(1) ifstream& operator= (const ifstream&) = delete;
move(2) ifstream& operator= (ifstream&& rhs);

等號運算子禁止使用左值引用,可以使用右值引用。(即右邊的值必須是一個即將銷燬的臨時物件)

Public member functions inherited from istream

7,std::istream::operator>>

輸入終端 cin 和 ifstream 都是 istream 的子類,所以輸入操作符 >> 用法相同。對變數進入輸入的時候過載了常用的資料型別。

arithmetic types (1)
istream& operator>> (bool& val);
istream& operator>> (short& val);
istream& operator>> (unsigned short& val);
istream& operator>> (int& val);
istream& operator>> (unsigned int& val);
istream& operator>> (long& val);
istream& operator>> (unsigned long& val);
istream& operator>> (long long& val);
istream& operator>> (unsigned long long& val);
istream& operator>> (float& val);
istream& operator>> (double& val);
istream& operator>> (long double& val);
istream& operator>> (void*& val);

stream buffers (2)
istream& operator>> (streambuf* sb );

manipulators (3)
istream& operator>> (istream& (pf)(istream&));
istream& operator>> (ios& (
pf)(ios&));
istream& operator>> (ios_base& (*pf)(ios_base&));

8,istream::gcount

streamsize gcount() const;

返回最後一個輸入操作讀取的字元數目。
可以修改這個返回值的函式有:get,getline,ignore,peek,read, readsome,putback and unget. 其中函式peek, putback and unget 被呼叫後gcount()返回值為0。

9,istream::get

single character (1): //讀取一個字元,遇到'\n',也從流中取出。
int get(); //字元按 int 返回
istream& get (char& c); // 讀到c中

//讀取n個 c 風格字串到陣列s中,遇到'\n'(或delim)停止讀取,並把'\n'留在輸入流中,若要讀取多行,就要需要int get() 來取出'\n',才能讀下一行。
c-string (2):
istream& get (char* s, streamsize n);//預設delim是換行字元'\n'
istream& get (char* s, streamsize n, char delim) //指定讀取停止字元 delim

stream buffer (3): //內容讀取到 streambuf 物件中。
istream& get (streambuf& sb);//預設delim是換行字元'\n'
istream& get (streambuf& sb, char delim);//指定讀取停止字元 delim

下面的程式演示get()讀取到streambuf 的用法。

include // std::cout, std::streambuf, std::streamsize

include // std::ifstream

using namespace std;

int main () {
std::ifstream ifs ("test.txt");
std::ofstream ofs ("out.txt");
std::streambuf *pbuf = ofs.rdbuf();

ifs.get(*pbuf);//預設讀取截止字元是'\n', 所以讀取一行停止,且沒有讀取'\n'。
pbuf->sputc(ifs.get()); // '\n'並沒有被讀取到pbuf,所以需要get()來讀取'\n',然後用函式sputc()加到 pbuf 中。
ifs.get(*pbuf);  // 從流中取出了'\n' ,才能讀取第二行
pbuf->sputc(ifs.get());
/*
上面使用了函式 istream& get (streambuf& sb); 
之後不能使用 istream& get (char* s, streamsize n);
*/
char s[20];       
ifs.get(s,20);//雖然輸入流有第三行,但是沒法讀取。
cout<<"get:"<<s<<endl;  //內容為空

ofs.close();
ifs.close();
return 0;

}

10,istream::getline

讀取一行到字元陣列。

istream& getline (char* s, streamsize n );
//預設delim是換行字元'\n',遇到後丟棄,第二次讀取從delim後開始讀。

istream& getline (char* s, streamsize n, char delim );
//自己定義停止符delim

字串標頭檔案也定義了從流中讀取一行的函式 getline()
因為它不是流的成員函式,所以不能通過點訪問。

std::getline (string)

(1) 使用者定義截止字元
istream& getline (istream& is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim); //c++11 標準

(2) 截止字元預設'\n'
istream& getline (istream& is, string& str);
istream& getline (istream&& is, string& str); // c++11 標準

用法:
從流物件is中讀取一行存到字串str 直到遇到截止字元,如果遇到截止字元,則把它從流中取出來,然後丟棄(它不被儲存,下一個操作的起點在它之後)函式呼叫前str 中的內容將被覆蓋。
demo: 讀取檔案流的內容

include

include

include

using namespace std;
int main()
{
string str;
ifstream ifs("test.txt");
if(!ifs){
cout<<"open file fail!"<<endl;
return 1;
}
while( getline(ifs,str))
{
cout<<str<<endl;
}
return 0;
}

11,istream::ignore

istream& ignore (streamsize n = 1, int delim = EOF);

從輸入流中讀取n個字元並且丟棄,或者讀到delim字元再停止讀取。

12,istream::peek

int peek();

返回輸入流下一個字元,並把它留在輸入流中,作為下一次讀取的起點。返回值是整形ascll碼值,可以用 char(c) 轉化為字元。

13,istream::read

istream& read (char* s, streamsize n);

從輸入流中提取n個字元,並把他們存陣列s中,不檢測內容,也不加字串結尾符號‘\0’,例項:

// read a file into memory

include // std::cout

include // std::ifstream

int main () {
std::ifstream is ("test.txt", std::ifstream::binary);
if (is) {
// get length of file:
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);

char * buffer = new char [length];

std::cout << "Reading " << length << " characters... ";
// read data as a block:
is.read (buffer,length);

if (is)
  std::cout << "all characters read successfully.";
else
  std::cout << "error: only " << is.gcount() << " could be read";
is.close();

// ...buffer contains the entire file...

delete[] buffer;

}
return 0;
}

14,istream::putback

istream& putback (char c);
// 用法,從輸入流讀取一個字元,再把它返回。
char c = std::cin.get();
std::cin.putback (c);

15,istream::unget

istream& unget();
// 返回最後一次讀取的字元到輸入流,類似putback()
char c = std::cin.get();
std::cin.unget();

16,istream::tellg

讀取輸入流中檔案指標的位置,返回值可轉化為 int。

streampos tellg();
// get length of file:
is.seekg (0, is.end);
int length = is.tellg();
is.seekg (0, is.beg);

17,istream::seekg

設定輸入流中檔案指標的位置。(1) 絕對位置 (2) 相對位置

(1)istream& seekg (streampos pos);
(2)istream& seekg (streamoff off, ios_base::seekdir way);

引數 pos 是流中的絕對位置可以轉化為 int
引數 off 是偏移量,與way相關,型別是 int
引數 way 可以選下表中的任意一個常量。

value offset is relative to…
ios_base::beg beginning of the stream
ios_base::cur current position in the stream
ios_base::end end of the stream
Public member functions inherited from ios

18,ios::good

bool good() const;
bool eof() const;
bool fail() const;
bool bad() const;

檢測流的狀態是否正常。當錯誤的狀態flags (eofbit, failbit and badbit) 都沒被設定的時候返回true
特定的錯誤狀態可以用下面的函式(eof, fail, and bad)來檢測。

iostate value (member constant) indicates good() eof() fail() bad() rdstate()
goodbit No errors (zero value iostate) true false false false goodbit
eofbit End-of-File reached on input operation false true false false eofbit
failbit Logical error on i/o operation false false true false failbit
badbit Read/writing error on i/o operation false false true true badbit
19,ios::operator!

bool operator!() const;
//Returns true if either failbit or badbit is set, and false otherwise.
// 有錯誤狀態返回 true

int main () {
std::ifstream is;
is.open ("test.txt");
if (!is)
std::cerr << "Error opening 'test.txt'\n";
return 0;
}

20,ios::operator bool

布林運算: 當流物件單獨出現在條件語句中時,就間接呼叫布林運算。
如:if(ios), while(ios)
函式原型:
c++98: operator void*() const;
c++11: explicit operator bool() const;
返回值:failbit 或 badbit 都沒被標記的時候返回真。
(對比good(): failbit 或 badbit 或 eofbit 都沒被標記的時候返回真)
布林運算一個很方便的用法就是檢測檔案結束。讀到檔案末尾的時候, eofbit, failbit 同時被設定為1,所以可以使用bool()來判斷流的狀態。
當檔案開啟失敗的時候failbit 位被設定為1,所以也能檢測開啟是否成功。

//按行讀檔案,簡潔的模板

include

include

include

using namespace std;

void print_state (const std::ios& stream)
{
cout << "good()=" << stream.good();
cout << " eof()=" << stream.eof();
cout << " fail()=" << stream.fail();
cout << " bad()=" << stream.bad()<<endl;
}
int main()
{
string str;
ifstream ifs("test.txt");
if(ifs)
{
//while( bool(getline(ifs,str)))// 等價
//while( getline(ifs,str).good())//等價
while( getline(ifs,str))
{
cout<<"line:"<<str<<endl;
}
}
else{
cout<<"open file fail!"<<endl;
return 1;
}
print_state(ifs);
return 0;
}

21,ios::rdstate

iostate rdstate() const;
// Returns the current internal error state flags of the stream.
// 返回當前流中的內部錯誤狀態,iostate二進位制數,需要做位運算來獲取其相應位置上的值。
//這個函式的功能可以被 good(),eof(),fail(),bad() 替換。
int main () {
std::ifstream is;
is.open ("test.txt");
if ( (is.rdstate() & std::ifstream::failbit ) != 0 )
std::cerr << "Error opening 'test.txt'\n";
return 0;
}