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 constant | stands for | access |
---|---|---|
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
,read
, readsome
,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
可以选下表中的任意一个常量
。
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
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 都没被标记的时候返回真)
布尔运算一个很方便的用法就是检测文件结束。读到文件末尾的时候, eofbit
, failbit
同时被设置为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 }
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