c++ 输入文件流ifstream用法详解[转]

目录

文章目录
输入流的继承关系:
成员函数
Public member functions
1, (constructor)
2,ifstream::open
3,ifstream:: is_open
4,ifstream:: close
5,ifstream:: rdbuf
6,ifstream:: operator =
Public member functions inherited from istream
7,std::istream::operator>>
8,istream::gcount
9,istream::get
10,istream::getline
11,istream::ignore
12,istream::peek
13,istream::read
14,istream::putback
15,istream::unget
16,istream::tellg
17,istream::seekg
Public member functions inherited from ios
18,ios::good
19,ios::operator!
20,ios::operator bool
21,ios::rdstate
输入流的继承关系:
ios_base <- ios <- istream <- ifstream

 

C++ 使用标准库类来处理面向流的输入和输出:

iostream 处理控制台 IO
fstream 处理命名文件 IO
stringstream 完成内存 string 的IO
每个IO 对象都维护一组条件状态 flags (eofbit, failbit and badbit),用来指出此对象上是否可以进行 IO 操作。如果遇到错误—例如输入流遇到了文件末尾,则对象的状态变为是失效,所有的后续输入操作都不能执行,直到错误纠正。

头文件 <fstream>包含的多个文件流类,这里列出常用的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可以省略。

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

2. ifstream::open

打开文件filename,模式默认 ios_base::in

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

函数参数:

  • filename 要打开文件的文件名
  • mode 打开文件的方式
member constantstands foraccess
in input File 读的方式打开文件
out output 写的方式打开文件
binary binary 二进制方式打开
ate at end 打开的时候定位到文件末尾
app append 所有操作都定位到文件末尾
trunc truncate 丢弃打开前文件存在的内容

3. ifstream:: is_open

1 bool is_open() const;

文件流对象与文件绑定,返回 true ,否则 false 。

4. ifstream:: close

1 void close();   //关闭文件流

5. ifstream:: rdbuf

1 filebuf* rdbuf() const;    

返回一个 filebuf 对象指针,(The pointer to the internal filebuf object.)

6. ifstream:: operator =

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

等号运算符禁止使用左值引用,可以使用右值引用。(即右边的值必须是一个即将销毁的临时对象)

Public member functions inherited from istream

7. std::istream::operator>>

输入终端 cin 和 ifstream 都是 istream 的子类,所以输入操作符 >> 用法相同。对变量进入输入的时候重载了常用的数据类型。

 1 arithmetic types (1)    
 2 istream& operator>> (bool& val);
 3 istream& operator>> (short& val);
 4 istream& operator>> (unsigned short& val);
 5 istream& operator>> (int& val);
 6 istream& operator>> (unsigned int& val);
 7 istream& operator>> (long& val);
 8 istream& operator>> (unsigned long& val);
 9 istream& operator>> (long long& val);
10 istream& operator>> (unsigned long long& val);
11 istream& operator>> (float& val);
12 istream& operator>> (double& val);
13 istream& operator>> (long double& val);
14 istream& operator>> (void*& val);
15 
16 stream buffers (2)    
17 istream& operator>> (streambuf* sb );
18 
19 manipulators (3)    
20 istream& operator>> (istream& (*pf)(istream&));
21 istream& operator>> (ios& (*pf)(ios&));
22 istream& operator>> (ios_base& (*pf)(ios_base&));

8. istream::gcount

1 streamsize gcount() const;

返回最后一个输入操作读取的字符数目。
可以修改这个返回值的函数有:get,getline,ignore,peek,readreadsome,putback and unget. 其中函数peek, putback and unget 被调用后gcount()返回值为0。

9. istream::get

 1 single character (1): //读取一个字符,遇到'\n',也从流中取出。
 2 int get(); //字符按 int 返回
 3 istream& get (char& c); // 读到c中
 4 
 5 //读取n个 c 风格字符串到数组s中,遇到'\n'(或delim)停止读取,并把'\n'留在输入流中,若要读取多行,就要需要int get() 来取出'\n',才能读下一行。
 6 c-string (2): 
 7 istream& get (char* s, streamsize n);//默认delim是换行字符'\n'
 8 istream& get (char* s, streamsize n, char delim) //指定读取停止字符 delim
 9 
10 stream buffer (3):  //内容读取到 streambuf 对象中。
11 istream& get (streambuf& sb);//默认delim是换行字符'\n'
12 istream& get (streambuf& sb, char delim);//指定读取停止字符 delim

下面的程序演示get()读取到streambuf 的用法。

#include <iostream>     // std::cout, std::streambuf, std::streamsize
#include <fstream>      // 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

读取一行到字符数组。

1 istream& getline (char* s, streamsize n );
2 //默认delim是换行字符'\n',遇到后丢弃,第二次读取从delim后开始读。
3 
4 istream& getline (char* s, streamsize n, char delim );
5 //自己定义停止符delim

<string> 字符串头文件也定义了从流中读取一行的函数 getline()
因为它不是流的成员函数,所以不能通过点访问。

    • std::getline (string)
1 (1)    用户定义截止字符
2 istream& getline (istream&  is, string& str, char delim);
3 istream& getline (istream&& is, string& str, char delim); //c++11 标准
4 
5 (2)    截止字符默认'\n'
6 istream& getline (istream&  is, string& str);
7 istream& getline (istream&& is, string& str); // c++11 标准

用法:
从流对象is中读取一行存到字符串str 直到遇到截止字符,如果遇到截止字符,则把它从流中取出来,然后丢弃(它不被存储,下一个操作的起点在它之后)函数调用前str 中的内容将被覆盖。
demo: 读取文件流的内容

 1 #include<iostream>
 2 #include<fstream>
 3 #include<string>
 4 using namespace std;
 5 int main()
 6 {
 7     string str;
 8     ifstream ifs("test.txt");
 9     if(!ifs){
10         cout<<"open file fail!"<<endl;
11         return 1;
12     }
13     while( getline(ifs,str))
14     {
15         cout<<str<<endl;
16     }
17     return 0;
18 }

11. istream::ignore

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

从输入流中读取n个字符并且丢弃,或者读到delim字符再停止读取。

12. istream::peek

1 int peek();

返回输入流下一个字符,并把它留在输入流中,作为下一次读取的起点。返回值是整形ascll码值,可以用 char© 转化为字符。

13. istream::read

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

从输入流中提取n个字符,并把他们存数组s中,不检测内容,也不加字符串结尾符号‘\0’,实例:

 1 // read a file into memory
 2 #include <fstream>  // std::ifstream
 3 #include <iostream> // std::cout
 4 #define LEN 10
 5 int main() {
 6   char buffer[LEN];
 7   buffer[LEN - 1] = '\0';
 8   std::ifstream is("test.txt", std::ifstream::binary);
 9 
10   if (is) {
11     while (is) {
12       is.read(buffer, LEN - 1);
13       //最后一次读取长度小于 LEN-1时候,会打印一些无效的字符
14       std::cout << "Reading " << is.gcount() << " characters. is:" << buffer
15                 << std::endl;
16     }
17     is.close();
18   }
19   return 0;
20 }

14. istream::putback

1 istream& putback (char c);
2 // 用法,从输入流读取一个字符,再把它返回。
3 char c = std::cin.get(); 
4 std::cin.putback (c);

15. istream::unget

1 istream& unget();
2 // 返回最后一次读取的字符到输入流,类似putback()
3 char c = std::cin.get();
4 std::cin.unget();

16. istream::tellg

读取输入流中文件指针的位置,返回值可转化为 int。

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

17. istream::seekg

设定输入流中文件指针的位置。(1) 绝对位置 (2) 相对位置

1 (1)istream& seekg (streampos pos);
2 (2)istream& seekg (streamoff off, ios_base::seekdir way);
  • 参数 pos 是流中的绝对位置可以转化为 int
  • 参数 off 是偏移量,与way相关,类型是 int
  • 参数 way 可以选下表中的任意一个常量
valueoffset 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

1 bool good() const;
2 bool eof() const;
3 bool fail() const;
4 bool bad() const;

19. ios::operator!

 1 bool operator!() const;
 2 //Returns true if either failbit or badbit is set, and false otherwise.
 3 // 有错误状态返回 true
 4 
 5 int main () {
 6   std::ifstream is;
 7   is.open ("test.txt");
 8   if (!is)
 9     std::cerr << "Error opening 'test.txt'\n";
10   return 0;
11 }

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 都没被标记的时候返回真)

布尔运算一个很方便的用法就是检测文件结束。读到文件末尾的时候, eofbitfailbit 同时被设置为1,所以可以使用bool()来判断流的状态。
当文件打开失败的时候failbit 位被设置为1,所以也能检测打开是否成功

 1 //按行读文件,简洁的模板
 2 #include<iostream>
 3 #include<fstream>
 4 #include<string>
 5 using namespace std;
 6 
 7 void print_state (const std::ios& stream) 
 8 {
 9     cout << "good()=" << stream.good();
10     cout << " eof()=" << stream.eof();
11     cout << " fail()=" << stream.fail();
12     cout << " bad()=" << stream.bad()<<endl;
13 }
14 int main()
15 {
16     string str;
17     ifstream ifs("test.txt");
18     if(ifs)
19     {
20         //while( bool(getline(ifs,str)))// 等价
21         //while( getline(ifs,str).good())//等价
22         while( getline(ifs,str))
23         {
24                cout<<"line:"<<str<<endl;
25         }
26     }
27     else{
28         cout<<"open file fail!"<<endl;
29         return 1;
30     }
31     print_state(ifs);
32     return 0;
33 }
  1. ios::rdstate 
 1 iostate rdstate() const;
 2 // Returns the current internal error state flags of the stream.
 3 // 返回当前流中的内部错误状态,iostate二进制数,需要做位运算来获取其相应位置上的值。
 4 //这个函数的功能可以被 good(),eof(),fail(),bad() 替换。
 5 int main () {
 6   std::ifstream is;
 7   is.open ("test.txt");
 8   if ( (is.rdstate() & std::ifstream::failbit ) != 0 )
 9     std::cerr << "Error opening 'test.txt'\n";
10   return 0;
11 }

原文链接:https://blog.csdn.net/sinat_36219858/article/details/80369255

posted on 2023-05-19 14:16  3D入魔  阅读(2041)  评论(0编辑  收藏  举报