输入输出--I/O流【C++提升】

1.1基础知识:

在C++中,输入输出(IO)流是通过标准库中的 <iostream> 头文件来处理的。C++ 提供了几种基本的输入输出流类,最常用的有以下几种:

  1. std::cin:用于输入。
  2. std::cout:用于输出。
  3. std::cerr:用于输出错误信息(无缓冲)。
  4. std::clog:用于输出日志信息(缓冲)。

基本使用示例

下面是一个简单的例子,展示如何使用这些 IO 流进行输入输出操作。

#include <iostream>  
#include <string>  int main() {  std::string name;  int age;  // 输出提示信息  std::cout << "请输入您的名字: ";  std::cin >> name; // 从标准输入读取名字  std::cout << "请输入您的年龄: ";  std::cin >> age; // 从标准输入读取年龄  // 输出结果  std::cout << "你好, " << name << "!你今年 " << age << " 岁。" << std::endl;  return 0;  
}

详细说明

  • 输入: 使用 std::cin 时,可以用 >> 运算符来读取不同类型的数据。默认情况下,它会忽略空白字符(空格、换行符等),直到遇到下一个有效的输入。

  • 输出: 使用 std::cout 进行输出时,可以用 << 运算符将多个数据连接在一起,可以很方便地输出多个变量及文本。

  • 错误输出std::cerr 和 std::clog 都用于输出错误信息,区别在于 std::cerr 是无缓冲的,意味着内容会立即输出,而 std::clog 是有缓冲的,可能会延迟输出。

注意事项

  1. 输入输出通常是在控制台进行的,要保证控制台能够接收和显示中文字符,可能需要设置locale。
  2. 使用 std::endl 时,它会在输出流中插入一个换行符,并刷新输出缓冲区。如果只需要换行,可以使用 \n,这样会提高效率,因为不一定每次都需要刷新。

1.2高级特性:

自定义输出格式

C++ 提供了多种方式来控制输出格式。你可以使用格式化标志和流操作符来改变输出格式。

#include <iostream>  
#include <iomanip> // 用于 std::setprecision 和 std::fixed  int main() {  double number = 123.456789;  std::cout << std::fixed << std::setprecision(2) << number << std::endl; // 输出 123.46  return 0;  
}

 流状态管理

C++ 允许你检查和管理流的状态。你可以检查流是否处于有效状态,是否发生了错误,是否到达文件结束等。

#include <iostream>  
#include <fstream>  int main() {  std::ifstream inFile("test.txt");  if (!inFile) {  std::cerr << "无法打开文件。" << std::endl;  return 1;  }  std::string line;  while (std::getline(inFile, line)) {  std::cout << line << std::endl;  }  if (inFile.eof()) {  std::cout << "到达文件结束。" << std::endl;  }  if (inFile.fail()) {  std::cout << "读取时发生错误。" << std::endl;  }  inFile.close();  return 0;  
}

流操作符的重载

你可以通过重载 << 和 >> 运算符来自定义对象的输入输出。

#include <iostream>  
#include <string>  class Person {  
public:  std::string name;  int age;  // 重载 << 运算符  friend std::ostream& operator<<(std::ostream& os, const Person& p) {  return os << p.name << " " << p.age;  }  // 重载 >> 运算符  friend std::istream& operator>>(std::istream& is, Person& p) {  return is >> p.name >> p.age;  }  
};  int main() {  Person p{"Alice", 30};  std::cout << p << std::endl; // 输出:Alice 30  Person p2;  std::cin >> p2; // 输入格式:<名字> <年龄>  std::cout << p2 << std::endl;   return 0;  
}

文件流异常处理

通过设置文件流的异常标志,可以更好地管理文件操作中的错误。

#include <iostream>  
#include <fstream>  int main() {  std::ifstream inFile;  inFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); // 设置异常标志  try {  inFile.open("nonexistent.txt"); // 尝试打开不存在的文件  } catch (const std::ifstream::failure& e) {  std::cerr << "异常: " << e.what() << std::endl;  }  return 0;  
}

使用字符串流

C++ 还提供了 std::ostringstream 和 std::istringstream 类,可以在内存中进行字符串流操作。

#include <iostream>  
#include <sstream>  int main() {  std::ostringstream oss; // 输出字符串流  oss << "Hello, " << "World! " << 2023;  std::string str = oss.str(); // 获取字符串  std::cout << str << std::endl; // 输出:Hello, World! 2023  std::istringstream iss(str); // 输入字符串流  std::string word;  while (iss >> word) { // 从字符串中读取单词  std::cout << word << std::endl;  }  return 0;  
}

文件缓冲管理

可以使用 std::ifstream 和 std::ofstream 的成员函数 rdbuf(),进行流缓冲区的操作。例如,你可以直接操作底层缓冲区,或者在特定情况下改变缓冲方式。

#include <iostream>  
#include <fstream>  int main() {  std::ofstream outFile("example.txt");  // 手动设置缓冲区  std::streambuf* originalBuf = std::cout.rdbuf(outFile.rdbuf());  std::cout << "这行将写入文件 example.txt" << std::endl;  // 恢复原来的缓冲区  std::cout.rdbuf(originalBuf);  std::cout << "这行将写入控制台" << std::endl;  return 0;  
}

使用标准库算法与流结合

可以将标准库算法与输入输出流结合使用,例如.sort()std::copy() 等,可以更加高效地处理数据。

#include <iostream>  
#include <vector>  
#include <algorithm>  
#include <iterator>  int main() {  std::vector<int> numbers = {5, 3, 4, 1, 2};  std::sort(numbers.begin(), numbers.end());  std::cout << "排序后的数字: ";  std::copy(numbers.begin(), numbers.end(), std::ostream_iterator<int>(std::cout, " "));  std::cout << std::endl;  return 0;  
}

 2.1文件操作:

在C++中,除了标准输入输出流(如std::cinstd::cout)外,文件输入输出也是常用的功能。可以通过标准库中的 <fstream> 头文件来处理文件的读取和写入。

文件操作基础

C++ 提供了以下几个主要的文件流类:

  1. std::ifstream:输入文件流,用于从文件中读取数据。
  2. std::ofstream:输出文件流,用于向文件中写入数据。
  3. std::fstream:文件流,可以同时用于读取和写入操作。

基本使用示例

以下是一个简单的示例,展示如何使用这几个类进行文件操作。

写入文件:

#include <iostream>  
#include <fstream>  
#include <string>  int main() {  std::ofstream outFile("output.txt"); // 创建输出文件流  if (!outFile) { // 检查文件是否成功打开  std::cerr << "无法打开文件进行写入。" << std::endl;  return 1;  }  outFile << "这是一行文本。\n";  outFile << "这是文件中的第二行。" << std::endl;  outFile.close(); // 关闭文件流  return 0;  
}

 读取文件:

#include <iostream>  
#include <fstream>  
#include <string>  int main() {  std::ifstream inFile("output.txt"); // 创建输入文件流  if (!inFile) { // 检查文件是否成功打开  std::cerr << "无法打开文件进行读取。" << std::endl;  return 1;  }  std::string line;  while (std::getline(inFile, line)) { // 逐行读取文件  std::cout << line << std::endl; // 输出到控制台  }  inFile.close(); // 关闭文件流  return 0;  
}

2.2高级特性:

文件打开模式:

可以指定打开文件的方式,如只读、只写、追加等。可以通过组合打开模式标志来实现,例如:

std::ofstream outFile("output.txt", std::ios::app); // 追加模式

 常用的模式标志有:

  • std::ios::in:打开文件用于读取。
  • std::ios::out:打开文件用于写入。
  • std::ios::app:以追加方式打开文件。
  • std::ios::trunc:打开文件时,如果文件存在,则先清空文件。
  • std::ios::binary:以二进制模式打开文件。

异常处理:

可以使用异常机制来处理文件操作中的错误。通过在文件流中设置异常标志:

std::ifstream inFile("somefile.txt");  
inFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);

 这将使得在文件打开或读取失败时抛出异常。

二进制文件的读写:

使用 std::ios::binary 打开文件,可以进行二进制数据的读写操作。例如,写入和读取基本数据类型或对象(如结构体)。

对象序列化:

可以通过重载 << 和 >> 运算符来实现自定义对象的输入输出。

class Person {  
public:  std::string name;  int age;  friend std::ostream& operator<<(std::ostream& os, const Person& p) {  os << p.name << " " << p.age;  return os;  }  friend std::istream& operator>>(std::istream& is, Person& p) {  is >> p.name >> p.age;  return is;  }  
};

3.0模拟实现:

模拟目标:

我们将创建一个名为 MyStream 的类,模拟 C++ 的输入输出流。这个类将支持字符串的读取和写入,并维护一个内部缓冲区。

代码示例: 

#include <iostream>  
#include <string>  
#include <sstream>  class MyStream {  
private:  std::string buffer;      // 内部缓冲区  size_t position;         // 当前读取位置  public:  MyStream() : position(0) {}  // 写入字符串到缓冲区  void write(const std::string& str) {  buffer += str;       // 追加字符串到缓冲区  }  // 从缓冲区读取字符串  bool read(std::string& outStr) {  if (position >= buffer.size()) {  return false; // 没有更多数据可读  }  // 查找下一个空格  size_t nextSpace = buffer.find(' ', position);  if (nextSpace == std::string::npos) {  nextSpace = buffer.size(); // 到达字符串末尾  }  // 提取子字符串  outStr = buffer.substr(position, nextSpace - position);  position = nextSpace + 1; // 更新当前位置  return true; // 成功读取  }  // 清空缓冲区  void clear() {  buffer.clear();  position = 0;  }  // 打印当前缓冲区的内容  void print() const {  std::cout << "Buffer: " << buffer << ", Position: " << position << std::endl;  }  
};  int main() {  MyStream myStream;  // 写入数据到自定义流  myStream.write("Hello World from MyStream");  myStream.print();  // 读取数据  std::string word;  while (myStream.read(word)) {  std::cout << "Read: " << word << std::endl;  }  // 再次写入新的数据  myStream.write("Another line");  myStream.print();  // 在读取新数据之前清空流  myStream.clear();  myStream.print();  // 再次写入数据  myStream.write("After clearing the buffer");  myStream.print();  // 读取新数据  while (myStream.read(word)) {  std::cout << "Read: " << word << std::endl;  }  return 0;  
}
  1. MyStream 类:

    • buffer 用于保存写入的数据。
    • position 用于记录当前读取的位置。
    • write 方法用于向缓冲区添加字符串。
    • read 方法用于从缓冲区读取下一个词并更新读取位置。如果没有可读的数据,返回 false
    • clear 方法用于清空缓冲区和重置位置。
    • print 方法用于打印当前的缓冲区内容和位置。
  2. main 函数:

    • 创建 MyStream 对象并写入示例字符串。
    • 读取缓冲区中的单词并打印。
    • 清空缓冲区后再次写入并读取。

尽管这只是一个基础示例,但它揭示了流机制的基本概念,如缓冲、读取位置和字符串处理。


感谢大家!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/454750.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netty无锁化设计之对象池实现

池化技术是比较常见的一种技术&#xff0c;在平时我们已经就接触很多了&#xff0c;比如线程池&#xff0c;数据库连接池等等。当我们要使用一个资源的时候从池中去获取&#xff0c;用完就放回池中以便其他线程可以使用&#xff0c;这样的目的就是为了减少资源开销&#xff0c;…

MySQL-23.多表查询-内连接

一.内连接 -- 多表查询 select * from tb_emp,tb_dept where tb_emp.dept_id tb_dept.id;-- 内连接 -- A.查询员工的姓名&#xff0c;及所属的部门名称&#xff08;隐式内连接实现&#xff09; select tb_emp.name as 员工姓名,tb_dept.name as 部门名称 from tb_emp,tb_dep…

简单介绍冯诺依曼体系

现代的计算机, 大多遵守冯诺依曼体系结构 CPU中央处理器&#xff1a;进行算术运算和逻辑判断。存储器&#xff1a;分为外存和内存&#xff0c;用于存储数据&#xff08;使用二进制方式存储&#xff09;。输入设备&#xff1a;用户给计算机发号施令。输出设备&#xff1a;计算机…

RISC-V笔记——Pipeline依赖

1. 前言 RISC-V的RVWMO模型主要包含了preserved program order、load value axiom、atomicity axiom、progress axiom和I/O Ordering。今天主要记录下preserved program order(保留程序顺序)中的Pipeline Dependencies(Pipeline依赖)。 2. Pipeline依赖 Pipeline依赖指的是&a…

LeetCode_2520. 统计能整除数字的位数_java

1、题目 2520. 统计能整除数字的位数https://leetcode.cn/problems/count-the-digits-that-divide-a-number/ 给你一个整数 num &#xff0c;返回 num 中能整除 num 的数位的数目。 如果满足 nums % val 0 &#xff0c;则认为整数 val 可以整除 nums 。 示例 1&#xff1a;…

TiDB替换Starrocks:业务综合宽表迁移的性能评估与降本增效决策

作者&#xff1a; 我是人间不清醒 原文来源&#xff1a; https://tidb.net/blog/6638f594 1、 场景 业务综合宽表是报表生成、大屏幕展示和数据计算处理的核心数据结构。目前&#xff0c;这些宽表存储在Starrocks系统中&#xff0c;但该系统存在显著的性能瓶颈。例如&#…

如何实现金蝶商品数据集成到电商系统的SKU

如何实现金蝶商品数据集成到电商SKU系统 金蝶商品数据集成到电商SKU的技术实现 在现代企业的数据管理中&#xff0c;系统间的数据对接与集成是提升业务效率和准确性的关键环节。本文将分享一个实际案例&#xff1a;如何通过轻易云数据集成平台&#xff0c;将金蝶云星辰V2中的商…

实战华为AC6508无线控制器+华为无线AP上线配置(AirEngine5762S-12+AirEngine5760-10)+无线WIFI配置

一、适用场景 1、适用于企业环境、校园环境、大户型家庭多层楼环境。 2、对于无线网络需要集中管理和监测的环境&#xff0c;无线wifi覆盖范围面积大&#xff0c;适用本实例。 3、当无线WIFI需要从一个区域到另一个区域无缝漫游时&#xff0c;确保应用不掉线&#xff0c;可使用…

简单有效修复d3d9.dll错误,11种d3d9.dll错误详细解决办法教程

当你遇到d3d9.dll文件丢失的问题时&#xff0c;可以通过今天的这篇文章详细的步骤来尝试修复这个问题&#xff0c;今天将教大家十一种d3d9.dll丢失修复的方法。 1. 重新安装DirectX以恢复d3d9.dll d3d9.dll是DirectX的一部分&#xff0c;因此重新安装DirectX通常可以解决d3d9.…

C#描述-计算机视觉OpenCV(7):MSER特征检测

C#描述-计算机视觉OpenCV&#xff08;7&#xff09;&#xff1a;MSER特征检测 基本概念操作实例效果优化 基本概念 前文C#描述-计算机视觉OpenCV&#xff08;6&#xff09;&#xff1a;形态学描述了如何对图像的前后景特征形态进行检测与运算&#xff0c;本篇将分析基于形态的…

Safari 中 filter: blur() 高斯模糊引发的性能问题及解决方案

目录 引言问题背景&#xff1a;filter: blur() 引发的问题产生问题的原因分析解决方案&#xff1a;开启硬件加速实际应用示例性能优化建议常见的调试工具与分析方法 引言 在前端开发中&#xff0c;CSS滤镜&#xff08;如filter: blur()&#xff09;的广泛使用为页面带来了各种…

大数据-173 Elasticsearch 索引操作 增删改查 详细 JSON 操作

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

后台管理员登录实现--系统篇

我的小系统后台原来就有一个上传图片的功能还夹带个删除图片的功能&#xff0c;还嵌到了一个菜单里面。之前效果如下 那么现在为了加大安全力度&#xff0c;想增加一个登录页面。通过登录再到这个页面。看着貌似很简单&#xff0c;但是听我细细说来&#xff0c;要新增些什么东西…

KMP 算法

目录 KMP 算法 算法思路 为什么不需要在主串中进行回退 计算 next 数组 代码实现 next 数组优化 查找所有起始位置 KMP 算法 KMP 算法是一种改进的字符串匹配算法&#xff0c;由 D.E.Knuth&#xff0c;J.H.Morris 和 V.R.Pratt 提出的&#xff0c;因此人们称它为 克努特…

(北京政务服务满意度公司)满意度调查助力服务质量提升

在当今社会&#xff0c;&#xff08;政务服务满意度公司&#xff09;政务窗口服务的质量直接关系到市民的日常生活和城市的健康发展。为了解市民对政务窗口服务的满意度&#xff0c;提升服务质量&#xff0c;某市委托民安智库专业市场调查公司开展了政务窗口服务满意度调查&…

【平方矩阵 + 蛇形矩阵】

矩阵找规律题 题目链接&#xff1a; 平方矩阵 I平方矩阵 II平方矩阵 III蛇形矩阵 平方矩阵 I 解法一&#xff1a;找坐标规律 while True:x int(input())if not x:breakfor i in range(x):for j in range(x):print(%d % min(i 1, j 1, x - i, x - j), end )print()prin…

【Hive】3-HiveSQL 数据定义语言(DDL)

HiveSQL 数据定义语言&#xff08;DDL&#xff09; SQL中DDL语法的作用 数据定义语言(Data Definition Language&#xff0c;DDL)&#xff0c;是SQL语言集中对数据库内部的对象结构进行创建&#xff0c;删除&#xff0c;修改等的操作语言&#xff0c;这些数据库对象包括datab…

SpringBoot实现的汽车票在线预订系统

2相关技术 2.1 MySQL 数据库 MySQL 是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非…

5G NR GSCN计算SSB中心频率MATLAB实现

本期给大家带来5G NR中已知GSCN如何计算SSB的中心频率&#xff0c;用MATLAB实现&#xff0c;参考3GPP 38.104 下图是GSCN与SSB中心频率换算关系。 函数说明&#xff1a; 函数的入参是GSCN号 函数的输出是对应的SSB中心频率&#xff0c;单位MHZ function freqency nr_5g_gs…

汽配企业数字工厂管理系统实施规划方案

在当今快速发展的汽车工业中&#xff0c;汽配企业面临着日益激烈的市场竞争和不断变化的客户需求。为了提升生产效率、优化资源配置并增强市场竞争力&#xff0c;实施数字工厂管理系统已成为汽配企业转型升级的关键举措。本方案旨在提出一套全面、可行的数字工厂管理系统实施规…