输入输出--I/O流【C++提升】()
1.1基础知识:
在C++中,输入输出(IO)流是通过标准库中的 <iostream>
头文件来处理的。C++ 提供了几种基本的输入输出流类,最常用的有以下几种:
std::cin
:用于输入。std::cout
:用于输出。std::cerr
:用于输出错误信息(无缓冲)。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
是有缓冲的,可能会延迟输出。
注意事项
- 输入输出通常是在控制台进行的,要保证控制台能够接收和显示中文字符,可能需要设置locale。
- 使用
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::cin
和std::cout
)外,文件输入输出也是常用的功能。可以通过标准库中的 <fstream>
头文件来处理文件的读取和写入。
文件操作基础
C++ 提供了以下几个主要的文件流类:
std::ifstream
:输入文件流,用于从文件中读取数据。std::ofstream
:输出文件流,用于向文件中写入数据。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;
}
-
MyStream
类:buffer
用于保存写入的数据。position
用于记录当前读取的位置。write
方法用于向缓冲区添加字符串。read
方法用于从缓冲区读取下一个词并更新读取位置。如果没有可读的数据,返回false
。clear
方法用于清空缓冲区和重置位置。print
方法用于打印当前的缓冲区内容和位置。
-
main
函数:- 创建
MyStream
对象并写入示例字符串。 - 读取缓冲区中的单词并打印。
- 清空缓冲区后再次写入并读取。
- 创建
尽管这只是一个基础示例,但它揭示了流机制的基本概念,如缓冲、读取位置和字符串处理。
感谢大家!
相关文章:

输入输出--I/O流【C++提升】()
1.1基础知识: 在C中,输入输出(IO)流是通过标准库中的 <iostream> 头文件来处理的。C 提供了几种基本的输入输出流类,最常用的有以下几种: std::cin:用于输入。std::cout:用于…...

Maven 中央仓库地址推荐
目录 Maven 中央仓库地址推荐 Maven Maven 中央仓库概述 什么是 Maven 中央仓库? 中央仓库的作用 常用的 Maven 中央仓库地址 官方 Maven 中央仓库 阿里云 Maven 中央仓库镜像 腾讯云 Maven 中央仓库镜像 网易 Maven 中央仓库镜像 华为云 Maven 中央仓库…...

Fastgpt本地化部署 - 以MAC为例
1.认识fastgpt 2.私有化部署 MongoDB:用于存储除了向量外的各类数据PostgreSQL/Milvus:存储向量数据OneAPI: 聚合各类 AI API,支持多模型调用 (任何模型问题,先自行通过 OneAPI 测试校验) (1&a…...

SpringBoot框架下购物推荐网站的设计模式与实现
3系统分析 3.1可行性分析 通过对本东大每日推购物推荐网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本东大每日推购物推荐网站采用JAVA作为开发语言&…...

Apache Flink 和 Apache Kafka
Apache Flink 和 Apache Kafka 都是大数据生态系统中非常重要的工具,但它们的作用和应用场景有所不同。下面将分别介绍两者的主要特性和它们之间的异同点。 Apache Kafka 作用: 消息队列:Kafka 主要作为消息队列使用,用于解耦生…...

Excel中Ctrl+e的用法
重点:想要使用ctrle,前提是整合或拆分后的结果放置的单元格必须和被提取信息的单元格相邻,且被提取信息的单元格也必须相连。 下图为错误示例 这样则可以使用ctrle 1、信息整合 2、提取信息 3、添加符号 4、信息顺序调换 5、数字提取 crtle还…...

07-Cesium动态处理线条闪烁材质的属性
这段代码定义了 LineFlickerMaterialProperty 类,用于管理线条闪烁材质的属性。构造函数接收颜色和速度作为选项,类包含动态属性 isConstant 和 definitionChanged,以及获取材质类型和当前属性值的方法。getValue 方法返回颜色和速度的当前值,equals 方法用于比较两个实例是…...

postgresql16分区表解析
PostgreSQL 16 引入了对分区表的多项改进,增强了其性能和可用性。本文介绍PostgreSQL 16 中分区表功能,包括基本概念、创建方法、管理技巧以及一些最佳实践。 分区表的基本概念 分区表是一种将大表物理分割成更小、更易管理的部分的技术。每个部分称为…...

文字识别解决方案-OCR识别应用场景解析
光学字符识别(Optical Character Recognition, OCR)技术是一种将图像中的文字转换为可编辑和可搜索的数据的技术。随着人工智能和机器学习的发展,OCR技术的应用场景越来越广泛,为文字录入场景带来了革命性的变革,下面以…...

Qt 每日面试题 -9
81、请写一个调用消息对话框提示报错的程序 QMessageBox::waring(this,tr("警告"), tr("用户名或密码错误!"),QMessageBox::Yes)82、Qt都提供哪些标准对话框以供使用,他们实现什么功能? Qt提供9个标准对话框: QColorDialog 颜色对话框&…...

K8s环境下使用sidecar模式对EMQX的exhook.proto 进行流量代理
背景 在使用emqx作为mqtt时需要我们需要拦截client的各种行为,如连接,发送消息,认证等。除了使用emqx自带的插件机制。我们也可以用多语言-钩子扩展来实现这个功能,但是目前emqx仅仅支持单个grpc服务端的设置,所以会有…...

Dirble:一款高性能目录扫描与爬取工具
今天给大家介绍的是一款名叫Dirble工具,它是一款易于使用的高性能网站目录扫描工具。该工具针对Windows和Linux平台设计,在Dirble的帮助下,广大安全研究人员可以快速对目标站点进行目录扫描和资源爬取。 工具安装 广大研究人员可以使用下列…...

C#语言基础
GitHub - babbittry/Csharp-notes: C# 课程笔记https://github.com/babbittry/Csharp-notes?tabreadme-ov-file#net%E6%98%AF%E4%BB%80%E4%B9%88 C# 数据类型 | 菜鸟教程 (runoob.com)https://www.runoob.com/csharp/csharp-data-types.html 语法基础 一、命名空间、类、方…...

网络分析仪——提升网络性能的关键工具
目录 什么是网络分析仪? 1. 实时流量监控 2. 历史数据回溯分析 3. 网络性能关键指标监测 4. 可视化界面与报告生成 总结 在当今的数字化世界,网络的稳定性和性能直接影响企业的运营效率。网络拥堵、延迟和丢包等问题会导致用户体验的下降ÿ…...

简单认识Maven 1
1.基本概念 Maven 是一个开源的项目管理和构建工具,主要用于 Java 项目,但也支持其他基于 JVM(Java Virtual Machine)的项目,如 Scala、Groovy 等。它基于项目对象模型(Project Object Model,P…...

鼠标右键删除使用Visual Studio 打开(v)以及恢复【超详细】
鼠标右键删除使用Visual Studio 打开(v) 1. 引言2. 打开注册表3. 进入对应的注册表地址4. 右键删除 AnyCode 项5. 效果6. 备份注册表文件——恢复菜单 1. 引言 安装完 Visual Studio 鼠标右键总有 “使用Visual Studio 打开(v)”,让右键菜单…...

如何缩短微商城系统推广周期
前言 微商城系统的推广周期是企业关注的重点之一。为了缩短推广周期,企业需要采取一系列有效的策略和措施。以下是对如何缩短微商城系统推广周期的详细介绍: 一、明确目标用户群体 在推广之前,企业需要明确自己的目标用户群体是谁…...

电脑如何清理重复文件?方法很简单!
清理重复文件能够有效释放存储空间,提高系统运行效率。长期堆积的重复文件会导致硬盘空间不足,从而影响系统性能。此外,清理文件还能帮助用户更好地管理和组织文件,避免因文件混乱而浪费时间。 常见的重复文件类型 重复文件可以是…...

【Linux】ioctl分析
简介 一个字符设备驱动通常会实现常规的open、release、read和write接口,但是如果需要扩展新的功能,通常以ioctl接口的方式实现。 #mermaid-svg-uY8EyPklf5e4ZMQo {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill…...

物联网通信会给人们的生活带来什么样的变化
物联网(IoT)通信的崛起正以前所未有的速度改变着人们的生活方式。从智能家居、智能交通到远程医疗、工业自动化,物联网技术的应用已经渗透到我们日常生活的方方面面。以下是对物联网通信如何具体影响并改变人们生活的详细探讨。 一、智能家居…...

Android 中获取当前 CPU 频率和占用率
最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下: 目前没有标准的 API 来获取 CPU 的使用频率,只能通过读取指定 CPU 文件获取当前 CPU 频率,在某些机器或者特定版本中…...

pymobiledevice3使用介绍(安装、常用命令、访问iOS沙盒目录)
项目地址:https://github.com/doronz88/pymobiledevice3 首先先介绍一下pymobiledevice3, pymobiledevice3是用Python3 实现的,用于处理 iDevices(iPhone 等)。它可以跨平台使用,支持:windows…...

python 爬虫模拟登录
在使用 Python 编写爬虫时,模拟登录是一个非常常见的需求,尤其是当你需要爬取需要身份验证的数据时。模拟登录通常需要以下步骤: 分析登录页面:确定提交登录请求的 URL 和相关参数。发送登录请求:模拟用户发送登录表单…...

AOP基础、快速入门、进阶
一、概述 AOP:Aspect Oriented Programming(面向切面编程、面向方面编程),其实就是面向特定方法编程 那什么又是面向方法编程呢,为什么又需要面向方法编程呢?来我们举个例子做一个说明: 比如…...

哪款宠物空净运行吸毛好、噪音小?希喂、霍尼韦尔、安德迈测评!
作为宠物领域目前最火热的产品,宠物空气净化器的讨论度一直很高。身为铲屎官的我在产品刚出的时候就购入了一台,结果让我非常失望! 抛开产品效果不提,它运行起来的声音实在太大了!我家猫根本不愿意靠近,每…...

新兴的安全职业挑战
我们经常与安全专业人士交谈,他们希望在努力提升职业发展的同时提高自己的价值并克服组织内部的挑战。在这些谈话中,花费大量时间讨论公司未来将面临的安全问题并不罕见。 安全领导者希望为问题制定计划并获得领导层对其计划的支持。这通常意味着实施修…...

代码随想录算法训练营Day32 | 122.买卖股票的最佳时机Ⅱ、55.跳跃游戏、45.跳跃游戏Ⅱ、1005.K次取反后最大化的数组和
目录 122.买卖股票的最佳时机Ⅱ 55.跳跃游戏 45.跳跃游戏Ⅱ 1005.K次取反后最大化的数组和 122.买卖股票的最佳时机Ⅱ 题目 122. 买卖股票的最佳时机 II - 力扣(LeetCode) 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i…...

3D Slicer 教程一
先了解一下什么是3D Slicer,这个是做什么,然后一步步了解功能,一起看看源码 一.初识 这块软件用来处理医学影像,是一款开源的软件. 里面涉及到一些 2d 常见的操作,图像处理,调窗,测量; 涉及到3d的一些常见重建,mpr,vr,cpr等, 还包括一些分割,变换等(越高级精确的一些通过插件…...

github pages + hugo 搭建静态博客网站
体验地址 1. 起因, 目的: 其实6年前,我就写过这个。 项目代码 博客地址 最近想改写一下。 github 推荐的主题是 Jekyll, 我当时用的就是这个,感觉很麻烦。尤其是文章命名。 新的主题 hugo 用起来还行。 2.过程: 过程记录&am…...

Python爬虫如何爬取并解析JSON数据
前言 Python爬虫是一种用于从互联网上获取数据的程序,而JSON(JavaScript Object Notation)是一种常用的数据交换格式。本文将介绍如何使用Python爬虫来爬取并解析JSON数据,同时还会讲解如何使用代理IP来提高爬取效率。 1. 什么是…...