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

c++输入文件流ifstream用法详解Andrew->China:SaysHelloNoterightofChina:Chinathinks\naboutitChina–&am

大家好,又见面了,我是你们的朋友全栈君。

目录

输入流的继承关系:

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可以省略。

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>>

输入终端 cinifstream 都是 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 <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

读取一行到字符数组。

istream& getline (char* s, streamsize n );
//默认delim是换行字符'\n',遇到后丢弃,第二次读取从delim后开始读。

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

<string> 字符串头文件也定义了从流中读取一行的函数 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<iostream>
#include<fstream>
#include<string>
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© 转化为字符。

13,istream::read

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

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

// read a file into memory
#include <fstream>  // std::ifstream
#include <iostream> // std::cout
#define LEN 10
int main() {
  char buffer[LEN];
  buffer[LEN - 1] = '\0';
  std::ifstream is("test.txt", std::ifstream::binary);

  if (is) {
    while (is) {
      is.read(buffer, LEN - 1);
      //最后一次读取长度小于 LEN-1时候,会打印一些无效的字符
      std::cout << "Reading " << is.gcount() << " characters. is:" << buffer
                << std::endl;
    }
    is.close();
  }
  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<iostream>
#include<fstream>
#include<string>
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;
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/130221.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 图像特征匹配方法——SIFT算法原理及实现

    图像特征匹配方法——SIFT算法原理及实现传统图像处理中图像特征匹配有三个基本步骤:特征提取、特征描述和特征匹配。特征提取就是从图像中提取出关键点(或特征点、角点)等。特征描述就是用一组数学向量对特征点进行描述,其主要保证不同的向量和不同的特征点之间是一种对应的关系,同时相似的关键点之间的差异尽可能小。特征匹配其实就是特征向量之间的距离计算,常用的距离有欧氏距离、汉明距离、余弦距离等。SIFT算法又叫尺度不变特征变换匹配算法,SIF…

    2022年6月22日
    130
  • shell 获取系统时间_shell脚本打印当前时间

    shell 获取系统时间_shell脚本打印当前时间在shell脚本里常常需要获取系统时间来处理某项操作,今天系统的学习了一下如何获取系统时间。记录如下:linux的系统时间在shell里是可以直接调用系统变量的如:获取今天时期:`date+%Y%m%d`或`date+%F`或$(date+%y%m%d)命令输出结果如下:[root@centi-C sh]# date +%Y%m%d 20120727 [root@c

    2022年10月10日
    3
  • 安全帽识别 安全帽佩戴识别 安全帽检测 安全帽分类 yolo安全帽识别

    安全帽识别 安全帽佩戴识别 安全帽检测 安全帽分类 yolo安全帽识别基于深度学习的安全帽佩戴检测安全帽识别安全帽检测安全帽分类yolo安全帽识别yolo安全帽tinyyolo安全帽识别安卓安全帽识别c++安全帽识别源码交流加wxdeeplearning_gogogo效果很棒,不服来战换不多说,奉上效果图…

    2022年5月19日
    40
  • 初学者:html中的表单详解(下面附有代码)

    初学者:html中的表单详解(下面附有代码)表单的理解与解释表单:采集不同类型的用户输入数据,发送给服务器,实现用户和服务器之间的数据交互。表单标签form声明数据采集的范围,只要是在form中的,都是要采集的数据。一个页面中可以有多个form标签,只能是并列关系,不能嵌套。只能是兄弟关系,,不能是父子关系。用户向服务器端发送数据时,一次只能提交一个表单中的数据。如果要提交多个表单就需要用js中的异步交互。表单元素method属性:提交表单时所用的http方法,默认为get方法。get方式:将数据作为url地址的一部分发送给服务器

    2022年8月11日
    6
  • 天气太冷不想出被窝?来DIY一个离线语音控制器[通俗易懂]

    天气太冷不想出被窝?来DIY一个离线语音控制器[通俗易懂]天气太冷不想出被窝?来DIY一个离线语音控制器点击上方“Embeded小飞哥”,选择“置顶/星标公众号”干货福利,第一时间送达!成就一番伟业的唯一途径就是热爱自己的事业。如果你还没能找到让自己热爱的事业,继续寻找,不要放弃。跟随自己的心,总有一天你会找到的。——乔布斯  你去关灯,你去,你去,。。我去。。小伙伴们有没有在天气寒冷时候,想去关灯,却离不开心爱的被窝的经历呢,有的话,跟着小飞哥一起来DIY一个离线语音控制器,有了它,我们

    2022年6月23日
    25
  • java中数组遍历的三种方式

    java中数组遍历的三种方式1.for循环遍历通常遍历数组都是使用for循环来实现。遍历一维数组很简单,遍历二维数组需要使用双层for循环,通过数组的length属性可获得数组的长度。2.Arrays工具类中toString静态方法遍历利用Arrays工具类中的toString静态方法可以将一维数组转化为字符串形式并输出。3.foreach语句遍历java5之后,Java提供了一种更简洁的循环:foreach循环,这种循环遍历数组和集合更加简洁。使用foreach循环遍历数组时,无须获得数组和集合长度,无须根据索引来访问数组

    2022年6月2日
    62

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号