文章目录
1.c++标准IO流
C++标准库提供了4个全局流对象cin、cout、cerr、clog,使用 cout 进行标准输出,即数据从内存流向控制台 ( 显示器 )。使用 cin 进行标准输入即数据通过键盘输入到程序中,同时C++标准库还提供了 cerr 用来进行标准错误的输出,以及 clog 进行日志的输出。
- 回车或者换行作为cin的终止输入符,因此如果输入字符串时,不能有回车和换行符,如果有读入带回车和换行的字符串就不能cin了,而用getline()
- cin和cout可以直接输入和输出 内置类型数据,原因:标准库已经将所有内置类型的输入和输出全部重载了
- 对于 自定义类型,如果要支持cin和cout的标准输入输出,需要对<<和>>进行重载。
- 发生错误时,系统需要立即输出以提醒用户,因此错误输出流对象 cerr 不具备缓冲区。
- cin为缓冲流。键盘输入的数据保存在缓冲区中,当要提取时,是从缓冲区中拿
#include<iostream>
using namespace std;
int main()
{
// 输入 hello world
string a;
cin >> a;
cout << a << endl; // hello
cin >> a;
cout << a << endl; // world
getline(cin,a);
cout << a << endl;
return 0;
}
2. C++文件IO流
fstream 输入输出
istream 只输入
ostream 只输出
2.1 成员函数
2.1.1 打开文件
open (filename, mode);
ios::in | 输入方式打开 |
---|---|
ios::out | 输出方式打开 |
ios::binary | 二进制方式打开 |
ios::ate | 初始位置在文件末尾 |
ios::app | 以追加方式打开 |
ios::trunc | 清除文件内容,并写入写内容 |
2.1.2 其他常用函数
(1). put 插入一个字符到文件
(2). write 插入一段字符到文件
(3). get 从文件提取字符
(4). read 从文件提取多个字符
(5). tellg 获取当前字符在文件当中的位置
(6). seekg 设置对文件进行操作的位置
(7). >>运算符重载 将数据形象地以“流”的形式进行输入(用于文本文件)
(8). <<运算符重载 将数据形象地以“流”的形式进行输出(用于文本文件)
(9).flush 与底层存储设备同步
2.2 代码示例
// 使用文件IO流用文本及二进制方式演示读写配置文件
struct ServerInfo
{
char _ip[32]; // ip
int _port; // 端口
};
struct ConfigManager
{
public:
ConfigManager(const char* configfile = "liren.config")
:_configfile(configfile)
{}
void WriteBin(const ServerInfo& info)
{
// 这里注意使用二进制方式打开写
ofstream ofs(_configfile, ifstream::out | ifstream::binary);
ofs.write((const char*)&info, sizeof(ServerInfo));
}
void ReadBin(ServerInfo& info)
{
// 这里注意使用二进制方式打开读
ifstream ifs(_configfile, ifstream::in | ifstream::binary);
ifs.read((char*)&info, sizeof(ServerInfo));
}
// C++文件流的优势就是可以对内置类型和自定义类型,都使用
// 一样的方式,去流插入和流提取数据
// 当然这里自定义类型Date需要重载>> 和 <<
// istream& operator >> (istream& in, Date& d)
// ostream& operator << (ostream& out, const Date& d)
void WriteText(const ServerInfo& info)
{
// 这里会发现IO流写整形比C语言那套就简单多了,
// C 语言得先把整形itoa再写
ofstream ofs(_configfile);
ofs << info._ip << endl << info._port << endl;
}
void ReadText(ServerInfo& info)
{
// 这里会发现IO流读整形比C语言那套就简单多了,
// C 语言得先读字符串,再atoi
ifstream ifs(_configfile);
ifs >> info._ip >> info._port;
}
private:
string _configfile; // 配置文件
};
int main()
{
ConfigManager cfgMgr;
ServerInfo winfo = { "192.0.0.1", 80, { 2022, 4, 10 } };
ServerInfo rdinfo;
// 二进制读写
cfgMgr.WriteBin(winfo);
cfgMgr.ReadBin(rdinfo);
cout << rdinfo._ip << endl;
cout << rdinfo._port << endl;
// 文本读写
cfgMgr.WriteText(winfo);
cfgMgr.ReadText(rdinfo);
cout << rdinfo._ip << endl;
cout << rdinfo._port << endl;
return 0;
}
3.字符串流
istringstream、ostringstream 和 stringstream,分别用来进行流的输入、输出和输入输出操作
3.1 将数值类型数据格式化为字符串
#include<sstream>
int main()
{
int a = 12345678;
string sa;
// 将一个整形变量转化为字符串,存储到string类对象中
stringstream s;
s << a;
s >> sa;
// clear()
// 注意多次转换时,必须使用clear将上次转换状态清空掉
// stringstreams在转换结尾时(即最后一个转换后),会将其内部状态设置为badbit
// 因此下一次转换是必须调用clear()将状态重置为goodbit才可以转换
// 但是clear()不会将stringstreams底层字符串清空掉
// s.str("")将stringstream底层管理string对象设置成"",
// 否则多次转换时,会将结果全部累积在底层string对象中
s.str("");
s.clear(); // 清空s, 不清空会转化失败
double d = 12.34;
s << d;
s >> sa;
string sValue;
sValue = s.str(); // str()方法:返回stringsteam中管理的string类型
cout << sValue << endl;
return 0;
}
🚩 运行结果:
12.34
3.2 字符串拼接
int main()
{
stringstream sstream;
// 将多个字符串放入 sstream 中
sstream << "first" << " " << "string,";
sstream << " second string";
cout << "strResult is: " << sstream.str() << endl;
// 清空 sstream
sstream.str("");
sstream << "third string";
cout << "After clear, strResult is: " << sstream.str() << endl;
return 0;
}
🚩 运行结果:
strResult is: first string, second string
After clear, strResult is: third string
3.3 序列化和反序列化结构数据
struct ChatInfo
{
string _name; // 名字
int _id; // id
Date _date; // 时间
string _msg; // 聊天信息
};
int main()
{
// 结构信息序列化为字符串
ChatInfo winfo = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧"};
stringstream oss;
oss << winfo._name << " " << winfo._id << " " << winfo._date << " " << winfo._msg;
// 通过str()可以获取oss中的字符串
string str = oss.str();
cout << str << endl << endl;
// 反序列化
// 我们通过网络这个字符串发送给对象,实际开发中,信息相对更复杂,
// 一般会选用Json、xml等方式进行更好的支持
// 字符串解析成结构信息
ChatInfo rInfo;
stringstream iss(str);
iss >> rInfo._name >> rInfo._id >> rInfo._date >> rInfo._msg;
cout << "-------------------------------------------------------" << endl;
cout << "姓名:" << rInfo._name << "(" << rInfo._id << ") ";
cout << rInfo._date << endl;
cout << rInfo._name << ":>" << rInfo._msg << endl;
cout << "-------------------------------------------------------" << endl;
return 0;
}
🚩 运行结果:
张三 135246 2022-4-10
晚上一起看电影吧
-------------------------------------------------------
姓名:张三(135246) 2022--4--10
张三:>晚上一起看电影吧
-------------------------------------------------------
参考链接:
https://blog.csdn.net/lirendada/article/details/126247398