前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++11基础内容

C++11基础内容

作者头像
芝士就是菜
发布2023-04-20 19:17:18
3820
发布2023-04-20 19:17:18
举报
文章被收录于专栏:芝士就是菜芝士就是菜

C++IO体系

ostream/istream 更好的支持自定义类型对象的流插入和流提取,自定义类型,可以自己重载,控制流提取和流插入的方式

输入输出

c输入

c++输入

代码语言:javascript
复制
cin >> str;

year = stoi(str.substr(0, 4));
mon = stoi(str.substr(4, 2));
day = stoi(str.substr(6, 2));

ctrl+z+换行结束输入

为什么可以用上边循环的写法呢?是因为cin的对象可以隐式类型转换成bool(调用operator bool),在流里面读到错误或者结束标志的时候,会返回false

举例详解:

代码语言:javascript
复制
class A
{
public:
 A(int a)  //这里前边加上explict,下边 A aa1 = 1 代码就编不过去了
  :_a(a)
 {}

 operator int() //如果这个前边加explict那么int i = aa1也不行,但是可以强转
 {
  return _a;
 }

private:
 int _a;
};

int main()
{
 // 内置类型 转换成自定义类型
 A aa1 = 1; // 隐式类型转换 用1构造A临时对象,再拷贝构造aa1,优化后直接1构造aa1

 // 自定义类型 转换成内置类型
 int i = aa1;

 return 0;
}

文件IO

C++根据文件内容的数据格式分为二进制文件和文本文件

定义一个文件流对象

  • ifstream ifile(只输入用)
  • ofstream ofile(只输出用)
  • fstream iofile(既输入又输出用)

看一个例子:

代码语言:javascript
复制
int main()
{
 ifstream ifs("test.cpp");
 char ch = ifs.get();

 while (ifs)
 {
  cout << ch;
  ch = ifs.get();
 }
 return 0;
}
代码语言:javascript
复制
这段程序可以读取当前文件的内容

C++特有的优点:

对内置的类型

对自定义的类型:

代码语言:javascript
复制
前题是自定义的类型支持流提取,这样对自定义类型的读写通过流的方式就非常的方便了。

两种读写方式对比

  1. 二进制读写:在内存如何存储,就如何写到磁盘文件 优点:快 缺点:写出去内容看不见
  2. 文本读写:对象数据序列化字符串写出来,读回来也是字符串,反序列化转成对象数据 优点:可以看见写出去是什么 缺点:存在一个转换过程,要慢一些

二进制读写

一个关于二进制读取string类型的坑

代码语言:javascript
复制
struct ServerInfo
{
 //char _address[32];
 string _address; // 换成string 类型
 int _port;  // 100

 Date _date;
};


struct ConfigManager
{
public:
 ConfigManager(const char* filename = "server.config")
  :_filename(filename)
 {}

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

 void ReadBin(ServerInfo& info)
 {
  ifstream ifs(_filename, ios_base::in | ios_base::binary);
  ifs.read((char*)&info, sizeof(info));
 }
private:
 string _filename; // 配置文件
};

int main()
{
 // 二进制写出去
 //ServerInfo winfo = { "127.0.0.1", 888 };
 //ServerInfo winfo = { "https://legacy.cplusplus.com/reference/istream/istream/read/", 888 };
 //ConfigManager cm;
 //cm.WriteBin(winfo);

 // 二进制的读
 ServerInfo rinfo;
 ConfigManager cm;
 cm.ReadBin(rinfo);
 cout << rinfo._address << endl;
 cout << rinfo._port << endl;

 return 0;
}

情况1、写入字符较短时

代码语言:javascript
复制
结果虽然读取成功,但是程序出现了问题,退出码不是0

情况2、写入字符串较长时

代码语言:javascript
复制
可以看到address直接读取报错

原因是当address比较长的时候,string对象,字符串会存在堆里面,ptr指针指向这个字符串,但是写到文件里面的时候,写的不是堆的内存,而是ptr这个地址。

二进制读写,不大适合有在堆上申请数据类型的

文本读写

下边是文本读写的方式:

代码语言:javascript
复制
 /*void WriteText(const ServerInfo& info)
 {
  ofstream ofs(_filename, ios_base::out);
  ofs.write(info._address.c_str(), info._address.size());
  ofs.put('\n');
  const string str = to_string(info._port);
  ofs.write(str.c_str(), str.size());
 }

 void ReadText(ServerInfo& info)
 {
  ifstream ifs(_filename, ios_base::in | ios_base::binary);
  char buff[128];
  ifs.getline(buff, 128);
  info._address = buff;

  ifs.getline(buff, 128);
  info._port = stoi(buff);
 }*/

 void WriteText(const ServerInfo& info)
 {
  ofstream ofs(_filename, ios_base::out);
  ofs << info._address << endl;
  ofs << info._port << endl;
  ofs << info._date << endl; //这里是日期类的对象
 }

 void ReadText(ServerInfo& info)
 {
  ifstream ifs(_filename, ios_base::in | ios_base::binary);
  ifs >> info._address >> info._port >> info._date;
 }

stringstream

一个例子:

代码语言:javascript
复制
struct ChatInfo
{
 string _name; // 名字
 int _id;      // id
 Date _date;   // 时间
 string _msg;  // 聊天信息
};


int main()
{
 // 序列化
 ChatInfo winfo = { "张三", 135246, { 2022, 4, 10 }, "晚上一起看电影吧" };
 //ostringstream oss;
 stringstream oss;
 oss << winfo._name << endl;
 oss << winfo._id << endl;
 oss << winfo._date << endl;
 oss << winfo._msg << endl;

 string str = oss.str();
 cout << str << endl;

 // 网络传输str,另一端接收到了字符串串信息数据

 // 反序列化
 ChatInfo rInfo;
 //istringstream iss(str);
 stringstream iss(str);
 iss >> rInfo._name;
 iss >> rInfo._id;
 iss >> rInfo._date;
 iss >> rInfo._msg;

 cout << "----------------------------------" << endl;
 cout << rInfo._date << endl;
 cout << rInfo._name << "[" << rInfo._id << "]:>" << rInfo._msg << endl;
 cout << "----------------------------------" << endl;

 return 0;
}

分割字符串:

代码语言:javascript
复制
int main()
{
 stringstream ss("sad ad fsd");
 string s;
 while (ss >> s)
 {
  cout << s << endl;
 }
 return 0;
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-02-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 芝士就是菜 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C++IO体系
    • 输入输出
      • c输入
      • c++输入
    • 文件IO
      • 二进制读写
      • 文本读写
    • stringstream
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档