C++的IO流

本文详细介绍了C语言中的输入输出以及C++的IO流机制,包括标准IO流cin、cout、cerr、clog的使用。讨论了C++中文件的二进制和文本读写操作,并通过实例展示了如何进行读写。此外,还简要说明了stringstream在数据转换中的应用。
摘要由CSDN通过智能技术生成

一、C语言的输入与输出

scanfprintf是C语言中最为常用的输入输出。
scanf(): 从标准输入设备(键盘)读取数据,并将值存放在变量中。
printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。
注意宽度输出和精度输出控制。
C语言借助了相应的缓冲区来进行输入与输出。
在这里插入图片描述
对于输入输出缓冲区的理解:

1.可以屏蔽掉低级I/O的实现,低级I/O的实现依赖操作系统本身内核的实现,所以如果能够屏蔽这部分的差异,可以很容易写出可移植的程序。
2.可以使用这部分的内容实现“行”读取的行为,对于计算机而言是没有“行”这个概念,有了这部分,就可以定义“行”的概念,然后解析缓冲区的内容,返回一个“行”。

二、流是什么

在这里插入图片描述
可以类比河流中流水一样,“流”即是流动的意思,是物质从一处向另一处流动的过程,是对一种有序连续且具有方向性的数据(其单位可以是bit,byte,packet)的抽象描述。 C++流是指信息从外部输入设备(如键盘)向计算机内部(如内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。
它的特性是:有序连续、具有方向性
为了实现这种流动,C++定义了I/O标准类库,这些每个类都称为流/流类,用以完成某方面的功能

三、C++IO流

读取文件大体上可以分为五步(之所以用in,读取文件这个行为对于程序来说相当于输入数据,所以用in,写文件的行为,是数据从程序中流出,所以用out。in,out都是相对于程序而言)。

读文件是in --> ifstream
写文件是out --> ofstream

C++系统实现了一个庞大的类库,其中ios为基类,其他类都是直接或间接派生自ios类
在这里插入图片描述

3.1 C++标准IO流

C++标准库提供了4个全局流对象cincoutcerrclog

  1. 使用cout进行标准输出,即数据从内存流向控制台(显示器)。
  2. 使用cin进行标准输入即数据通过键盘输入到程序中,
  3. 同时C++标准库还提供了cerr用来进行标准错误的输出,
  4. 使用clog进行日志的输出,

从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象,因此这三个对象现在基本没有区别,只是应用场景不同,在使用时候必须要包含文件并引入std标准命名空间

注意

  1. cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿。如果一次输入过多,会留在那儿慢慢用,如果输入错了,必须在回车之前修改,如果回车键按下就无法挽回了。只有把输入缓冲区中的数据取完后,才要求输入新的数据。
  2. 输入数据类型必须与要提取的数据类型一致,否则出错。出错只是在流的状态字state中对应位置(置1),程序继续。
  3. 空格回车都可以作为数据之间的分格符,所以多个数据可以在一行输入,也可以分行输入。但如果是字符型和字符串,则空格(ASCII码为32)无法用cin输入,字符串中也不能有空格。回车符也无法读入。使用getline()输入。
  4. cin和cout可以直接输入和输出内置类型数据,原因:标准库已经将所有内置类型的输入和输出全部重载了。
  5. 对于自定义类型,如果要支持cin和cout标准输入输出,需要重载<<和>>
  6. 在线OJ常用:
    常常要求多组测试用例:
//C语言中
while(scanf("%d\n",&a)!=EOF)
{
	//数据处理
	//ctrl+z退出
}
//C++中
while(cin>>str)
{
	//数据处理
}

对于C++中的cin>>str,调用operator>>重载,转换为operator>>(cin,str),输入接收是用的对象作为while循环的判断条件,这显然是不合常理的,但是这里却是一个特殊的函数重载operator.bool( )
举个例子:

istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

这里返回in,其实就是返回cin(这是一个对象)
cin中又提供了对于类型运算符的重载operator bool,它会返回一个是否设置了错误标志(failbit或badbit)。

while(对象)
{} 
转换成
while(对象.operator bool())
{}

如下例子:


class B
{
public:
	operator bool()
	{
		return _a != 0;
	}
	int _a;
};
int main()
{
	B b;
	/*while (b)*/  // 等价于
	while (b.operator bool())
	{
		cin >> b._a;
	}
	return 0;
}

3.2 C++中文件读写操作

要求:往配置文件中写入和读取信息

struct ServerInfo
{
	char _ip[32];
	int _port;
};

class ConfigManager
{
public:
	ConfigManager(const char* filename)
		:_filename(filename)
	{}
	void WriteBin(const ServerInfo & info)
	{
		// out到文件中
		ofstream ofs(_filename.c_str(),ios_base::out|ios_base::binary);
		ofs.write((const char*)&info,sizeof(ServerInfo));
	}
	void ReadBin(const ServerInfo& info)
	{
		ifstream ifs(_filename.c_str(), ios_base::in | ios_base::binary);
		ifs.read(( char*)&info, sizeof(ServerInfo));
	}

	void WriteText(const ServerInfo& info)
	{
		ofstream ofs(_filename.c_str());
		ofs << info._ip <<" "<< info._port ;

	}void ReadText(ServerInfo& info)
	{
		ifstream ifs(_filename.c_str());
		ifs >> info._ip >> info._port;
	}
private:
	string  _filename;
};

二进制读写

// 写入
void TestBinWite()
{
	ServerInfo info = { "126.0.0.1",90 };
	ConfigManager cm("config.bin");
	cm.WriteBin(info);
}
// 读取
void TestBinRead()
{
	ServerInfo info ;
	ConfigManager cm("config.bin");
	cm.ReadBin(info);
	cout << info._ip <<":"<< info._port << endl;
}

结果展示:
在这里插入图片描述

文本读写

// 文本写入
void TestTextWrite()
{
	ServerInfo info = { "126.0.0.1",90 };
	ConfigManager cm("config.txt");
	cm.WriteText(info);
}
// 文本读取
void TestTextRead()
{
	ServerInfo info;
	ConfigManager cm("config.txt");
	cm.ReadText(info);
	cout << info._ip << ":" << info._port << endl;
}

结果展示:
在这里插入图片描述

四、stringstream的简单介绍

主要用途:将一些数据转换成一个字符串,或者将字符串转为数字

struct Personinfo {
	string _name;
	int _age;
};
void Teststringstream()
{
	// 序列化
	Personinfo p = {"张三",18};
	ostringstream oss;
	oss << p._name <<" "<< p._age;
	string str = oss.str();
	cout << str<<endl;
	// 反序列化
	istringstream iss(str);
	string name;
	int age;
	iss >> name>>age;
	cout << name << " " << age << endl;
}

要使用stringstream,必须要包含头文件<sstream>。在该头文件下,有三个类:

  1. ostringstream 输出操作
  2. istringstream 输入操作
  3. stringstream 输入操作+输出操作
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值