C++学习记录——삼십이 C++IO流

这篇具有很好参考价值的文章主要介绍了C++学习记录——삼십이 C++IO流。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1、C++标准IO流

C语言的printf和scanf无法很好的输入输出自定义类型,且还需要程序员自己确定类型,所以C++就引入了输入流和输出流,是设备和内存之间的沟通。

C++学习记录——삼십이 C++IO流,C++学习,c++,学习,开发语言

其实iostream是通过菱形继承实现的。cout,cerr,clog其实做得有时候没有区分

int main()
{
	cout << "1111" << endl;
	cerr << "2222" << endl;
	return 0;
}

也都能打印出来。fstream和sstream是针对文件和字符串的,对应的就是fprintf/fscanf,fwrite/fread,sprintf/sscanf。C++IO流的特点就是面向对象以及能更好地支持自定义类对象的IO。

istream和ostream是防止拷贝的。

C++IO流的缓冲区和C语言的缓冲区会进行同步,比如用cout和printf混合着输出,也能输出。默认开着同步,也可以关闭同步增强效率。和这个接口有关

C++学习记录——삼십이 C++IO流,C++学习,c++,学习,开发语言

实现了迭代器的容器,通常就不需要重载IO流。

	string str;
	while (cin >> str)
	{
		cout << str << endl;
	}

这样的写法,就可以持续写入字符串,想要停止,就用ctrl + z + 换行来停止,这样是将流对象提取到结束,如果是ctrl + c就是信号强杀进程。我们要知道此时cin >> str是在做什么,>>右边的数据会被获取,给到cin,如果有多个,那就获取多个,最终都流向cin,然后返回一个istream类型的对象,这个对象会被转为bool类型来进行判断,但是一些自定义类型不可以转,像string,而istream可以转是因为类里重载了一个bool()函数,支持自定义类型转内置类型。

在之前的博客中,写到过单参数构造的类支持隐式类型转换

class A
{
public:
	A(int a)
		:_a(a)
	{}
private:
	int _a;
};

int main()
{
	A aa1 = 1;
	return 0;
}

这里的内部实现其实是构造一个临时对象,然后用这个对象来拷贝构造aa1,如果是A&就不行了。这是内置类型转自定义类型,但是自定义转内置不可:int x = aa1。解决办法就是重载一个类型()函数。

	operator int()
	{
		return _a;
	}

如果该函数前面加上explicit就不行了,不过在下面写int x = (int)aa1,强制转换一下也行。

istream里的operator bool(),如果被设置成错误的信息,就返回false,否则返回true,错误的信息例如ctrl + Z + 换行。

2、C++文件IO流

1、二进制读写

#include <fstream>
using namespace std; 

int main()
{
	ofstream ofs("F://test.txt");
	ofs << "hello world";
	return 0;
}

默认是覆盖写,第二个模板参数默认是ios_base::openmode mode = ios_base::out,ios_base是ofstream和ifstream的父类,如果想要用其它写入模式

C++学习记录——삼십이 C++IO流,C++学习,c++,学习,开发语言

是用 | 来隔开的。

int main()
{
	ofstream ofs("F://test.txt", ofstream::out | ofstream::app);
	ofs << "hello world";
	return 0;
}

看一个读写都有的代码

struct ServerInfo
{
	char _address[32];
	int _port;
	Date _date;
};

struct ConfigManager
{
public:
	ConfigManager(const char* filename)
		:_filename(filename)
	{}

	void WriteBin(const ServerInfo& info)
	{
		ofstream ofs(_filename, ofstream::out | ofstream::binary);
		ofs.write((const char*)&info, sizeof(info));
	}

	void ReadBin(ServerInfo& info)
	{
		ifstream ifs(_filename, ofstream::in | ofstream:::binary);
		ifs.read((char*)&info, sizeof(info));
	}

private:
	string _filename; // 配置文件
};

int main()
{
	ServerInfo winfo = { "192.0.0.1", 80, {2023, 9, 4} };
	string str;
	cin >> str;
	if (str == "二进制写")
	{
		ConfigManager cm("F://test.txt");
		cm.WriteBin(winfo);
	}
	else if (str == "二进制读")
	{
		ServerInfo rinfo;
		ConfigManager cm("F://test.txt");
		cm.ReadBin(rinfo);
		cout << rinfo._address << endl;
		cout << rinfo._port << endl;
		cout << rinfo._date << endl;
	}
	return 0;
}

二进制读写对象中不能用string,能读进去,但是会崩,而且如果输入的字符串比较长那基本上就是崩掉。

二进制写时,写到文件的是string对象及里面指向空间的指针,程序结束,string自动析构,指针指向的空间销毁了,所以就没法读取,读到的就是野指针。

二进制读写的优点就是简单易操作,缺点就是没法看到实体。

2、文本读写

C语言文本读写的本质是内存中任何类型都转成字符串来交互,C++封装运算符重载后就变得更高效了。

	void WriteText(const ServerInfo& info)
	{
		ofstream ofs(_filename);
		ofs << info._address << " " << info._port << " " << info._date;
	}

日期类中实现了对流插入流提取的重载,不仅ostream能使用,ofstream和osstream都可以用,因为使用了继承体系,ostream是它们的父类。istream也是如此。

	void WriteText(const ServerInfo& info)
	{
		ofstream ofs(_filename);
		ofs << info._address << endl;
		ofs << info._port << endl;
		ofs << info._date << endl;
	}
	void ReadText(ServerInfo& info)
	{
		ifstream ifs(_filename);
		ifs >> info._address;
		ifs >> info._port;
		ifs >> info._date;
	}
	
	else if (str == "文本写")
	{
		ConfigManager cm("F://test.txt");
		cm.WriteText(winfo);
	}
	else if (str == "文本读")
	{
		ServerInfo rinfo;
		ConfigManager cm("F://test.txt");
		cm.ReadText(rinfo);
		cout << rinfo._address << endl;
		cout << rinfo._port << endl;
		cout << rinfo._date << endl;
	}

3、stringstream

对应C语言的sprintf和sscanf。

C++学习记录——삼십이 C++IO流,C++学习,c++,学习,开发语言

就像最上面那个图中显示,ios_base是一个基类,ios是它的派生类,istream和ostream是ios的派生类,iostream是istream和ostream的组合,然后istream,ostream,iostream各有分支,stingstream继承于iostream,istringstream继承于istream,ostringstream继承于ostream。

头文件是sstream,不是stringstream。

int main()
{
	ostringstream oss;
	oss << 100 << " ";
	oss << 11.22 << " ";
	oss << "hello  wolrd" << endl;
	string str = oss.str();
	cout << str << endl;
	return 0;
}

可以把流插入的内容转换成一个字符串,也可以提取出来。

int main()
{
	ostringstream oss;
	oss << 100 << " ";
	oss << 11.22 << " ";
	oss << "hello  wolrd" << endl;
	string str = oss.str();
	cout << str << endl;

	istringstream iss(str);
	int i;
	double d;
	string s;
	iss >> i >> d >> s;
	cout << i << endl;
	cout << d << endl;
	cout << s << endl;
	return 0;
}

iss后面的顺序也得和oss拿到的顺序一样,要不然会使得某些变量内容不对,但也能打印出来。oss和iss也可以换成stringstream的类型。

这个功能主要用于序列化和反序列化

struct ChatInfo
{
	string _name;
	int _id;
	string _msg;
};

int main()
{
	ChatInfo winfo = { "张三", 123456, "你好" };
	return 0;
}

像这样,我们就可以用ostringstream把内容放到一个字符串,然后发送给需要这些信息的人,别人收到后,就可以用istringstream来提取。不过插入的时候每个后面都加上换行或者空格,因为提取时默认以换行或者空格来分割。

复杂的实际情况还有其它方法。

C++IO流

结束。文章来源地址https://www.toymoban.com/news/detail-696675.html

到了这里,关于C++学习记录——삼십이 C++IO流的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • openPLC_Editor C语言编程 在mp157 arm板上调用io等使用记录

    1.编程界面比较简单,具备PLC开发编程的四种编程方式。梯形图语言LD ,指令表语言IL,结构化文本语言ST,功能模块图语言FBD。  2.官方使用手册。学习资料实在是太少,目前都是自己比较费劲的研究。         3.2 Creating Your First Project on OpenPLC Editor – Autonomy  3.openplc 在其

    2024年04月10日
    浏览(44)
  • Linux学习记录——사십일 高级IO(2)--- Select型服务器

    select就是多路转接IO。select能以某种形式,等待多个文件描述符,只要有哪个fd有数据就可以读取并全部返回。就绪的fd,要让用户知道。select等待的多个fd中,一定有少量或者全部都准备好了数据。 nfds输入型参数,表示select等待的多个fd中,fd对应的数 + 1 剩下四个参数都是输

    2024年01月16日
    浏览(52)
  • 记录协助Javaer硬件快速开发过程之Web技术栈对接施耐德网络IO网关

    前一段时间有个Java技术栈的朋友联系到我,需要快速对接现有的无人值守称重系统,这里的对接是指替代现有系统,而非软件层面的对接,也就是利用现有的硬件开发一套替代现有软件的自动化系统。主要设备包括地磅秤、道闸、红外对射传感器、摄像头、小票打印、LED显示

    2024年04月13日
    浏览(41)
  • Linux学习记录——사십삼 高级IO(4)--- Epoll型服务器(1)

    poll依然需要OS去遍历所有fd。一个进程去多个特定的文件中等待,只要有一个就绪,就使用select/poll系统调用,让操作系统把所有文件遍历一遍,哪些就绪就加上哪些fd,再返回。一旦文件太多了,遍历效率就显而易见地低。epoll是为处理大批量句柄而作了改进的poll,句柄就是

    2024年01月18日
    浏览(50)
  • Linux学习记录——사십오 高级IO(6)--- Epoll型服务器(3)(Reactor)

    看完前两篇再看这篇,本篇将会写Reactor EpollServer.hpp中创建一个函数HandlerRequest,用它来做Recver函数的数据处理,也就是数据分析。 改一下回调函数,不向外暴露Connection类。 Main.cc中就不需要两个函数,一个计算函数就可以 处理数据那里再加上最后的步骤 回到Recver函数,调用

    2024年01月23日
    浏览(55)
  • Linux学习记录——사십사 高级IO(5)--- Epoll型服务器(2)(Reactor)

    本篇基于上篇代码继续改进,很长。关于Reactor的说明在后一篇 上面的代码在处理读事件时,用的request数组是临时的,如果有数据没读完,那么下次再来到这里,就没有这些数据了。所以得让每一个fd都有自己的缓冲区。建立一个Connection类,然后有一个map结构,让这个类和每

    2024年01月20日
    浏览(55)
  • Linux学习记录——사십사 高级IO(6)--- Epoll型服务器(3)(Reactor)

    看完前两篇再看这篇,本篇将会写Reactor EpollServer.hpp中创建一个函数HandlerRequest,用它来做Recver函数的数据处理,也就是数据分析。 改一下回调函数,不向外暴露Connection类。 Main.cc中就不需要两个函数,一个计算函数就可以 处理数据那里再加上最后的步骤 回到Recver函数,调用

    2024年01月20日
    浏览(42)
  • 【C++学习】线程库 | IO流 | 空间配置器

    🐱作者:一只大喵咪1201 🐱专栏:《C++学习》 🔥格言: 你只管努力,剩下的交给时间! 在C++11之前,涉及到多线程问题,都是和平台相关的,比如windows和linux下各有自己的接口,这使得代码的可移植性比较差。 C++11中最重要的特性就是支持了多线程编程,使得C++在并行编程

    2024年02月12日
    浏览(48)
  • 【C++初阶(一)】学习前言 命名空间与IO流

    本专栏内容为:C++学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C++。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C++ 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 C++是基于C语言而产生的,它既可以进行C语言的

    2024年02月08日
    浏览(95)
  • 从C语言到C++_38(C++的IO流+空间适配器)STL六大组件联系

    目录 1. C语言的输入和输出和流 2. C++的IO流 2.1 C++标准IO流 2.2 C++文件IO流 2.3 stringstream(字符流) 3. 空间配置器(了解) 3.1 一级空间适配器 3.2 二级空间配置器 3.3 二级空间适配器的空间申请 3.4 二级空间配置器的空间回收 3.5 对象构造与释放和与容器结合 4. STL六大组件联系

    2024年02月09日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包