C++输入输出与IO流

C++ 输入输出与I/O流

文章目录

  • C++ 输入输出与I/O流
    • IO类型与基础特性
      • 概念与特性
      • IO状态
      • 输出缓冲区
    • 文件输入输出
      • 文件模式
    • string流
    • IO处理中常用的函数及操作符
    • 综合练习与demo
      • 一、 创建文件并写入
      • 二、控制台输入数据并拆分存储
      • 三、读写电话簿

IO类型与基础特性

C++11标准提供了几种IO处理操作。其中最为熟悉的就是控制台IO:iostream,除此之外,还提供了文件操作IO:fstream以及string处理IO:stringstream,这两种IO操作都继承自iostream,因此在iostream上可以执行的操作,在另外两种IO类型中亦可执行。(i继承i,o继承o)

IO库类型及头文件

头文件类型作用
iostreamistream, wistream从流读取数据
ostream, wostream向流写入数据
iostream, wiostream读写流
fstreamifstream, wifstream从文件中读取数据
ofstream, wofstream向文件写入数据
fstream, wfstream读写文件
sstreamistringstream, wistringstream从string中读取数据
ostringstream, wostringstream向string中写入数据
stringstream, wstringstream读写string

注:w开头的类型用于操纵wchar_t类型的数据。

  • cin:一个istream对象,从标准输入中读取数据
  • cout: 一个ostream对象,向标准输出写入数据
  • cerr:一个ostream对象,通常用于输出程序错误信息,写入到标准错误
  • >>:用来从一个istream对象读取输入数据
  • <<: 用来向一个ostream对象写入输出数据
  • eof(): 用来判断流是否到达末尾

概念与特性

  • IO对象不能被拷贝或赋值
  • 如果程序崩溃,输出缓冲区是不会被刷新的。
  • 当一个输入流被关联到一个输出流时,任何试图从输入流读取数据的操作都会先刷新关联的输出流

IO状态

strm::iostate是C++中表示流的状态的一种类型,是一个枚举类型。(这里的strm是一种IO类型,如ostreamfstream等)

流状态类型说明
strm::badbit**表示流发生了无法恢复的错误,通常是系统级错误。**如果其对应置位被clear()清除,也只是将流状态恢复为有效,不会解决问题。
strm::falibit表示流操作失败,这种错误通常是可恢复的
strm::eofbit表示流到达了文件结束
strm::goodbit表示流处于正常状态,所有的标志位都是0

标准库提供了一组函数用来查询这些标志位的状态。其中good()fail()是确定流总体状态的方法,当我们将流当做条件使用,如while(cin >> word)时,其代码就等价于while(!cin.fail())

状态查询方法说明
s.eof()若流s的eofbit置位,则返回true
s.fail()若流s的falibitbadbit置位,则返回true
s.bad()若流s的badbit置位,则返回true
s.good()若流s处于有效状态,则返回true
s.clear()将流s中所有条件状态复位,将流的状态设置为有效。void类型
s.clear(flags)复原指定的flags标志位。void类型
s.setstate(flags)复原给定的flags标志位。void类型
s.rdstate()返回的是当前流的状态,以 iostate 枚举值表示。

输出缓冲区

每个输入流都管理一个缓冲区,用来保存程序读写的数据。

当程序正常结束、缓冲区满、手动指定缓冲(如操作符endl,cerr等)缓冲区都会被刷新。

操作符说明
std::endl换行并刷新缓冲区
std::flush刷新缓冲区,且不附加额外字符
std::ends输出空字符,并刷新缓冲区

unitbuf与nounitbuf

cout << unitbuf; 		// 所有输出操作后都会立刻刷新缓冲区
// 任何输出都立刻刷新,无缓冲
...
cout << nounitbuf;      // 恢复常规模式

文件输入输出

fstream特有的操作

操作说明
fstream fstrm;创建一个未绑定的文件流
fstream fstrm(s);创建一个文件流,并打开名为s的文件(s可为string,亦可为C风格字符串之指针)。此构造函数是explicit的
fstream fstrm(s, mode)与上者类似,按指定mode打开指定s文件
fstrm.open(s)打开名为s的文件,并将文件与fstrm绑定
fstrm.close()关闭与fstrm绑定的文件。void类型
fstrm.is_open()返回一个bool值,说明关联文件是否成功打开且尚未关闭
  • 当一个fstream对象被销毁时,close会自动被调用

文件模式

文件模式,用于指出文件流如何使用文件

文件模式说明
in以读的方式打开
out以写的方式打开
app每次写操作之前均定位到文件末尾
ate打开文件后立即定位到文件末尾
trunc截断文件
binary以二进制方式进行IO
  • ifstream默认in模式,ofstream默认out模式,fstream默认inout模式
  • out只支持ofs和fs流; in只支持ifs和fs流
  • out被设定时,才可以设定trunc
  • trunc没被设定时,才可以设定app模式
  • app模式下,没有显式指定out,文件依然以输出方式被打开
  • atebinary模式可用于任何类型的文件流对象

注意1:以out模式打开文件会丢弃已有数据

  • 使用ofstream打开一个文件,会将文件原有的数据丢弃。可以同时采用显式指定appin的方式打开,避免造成数据丢失。

注意2:每次调用open是都会确认文件模式

  • 我们使用同一个ofstream流打开文件,在第一个文件指定了什么模式打开,并不会在第二个文件中依然存在,只会选择默认方式
  • 所以我们利用与out相关的文件流打开文件时,一定要注意最好显式指定文件模式

我们使用文件流时通常包含以下步骤

  • 创建一个文件流
    • 默认文件流
    • 指定绑定文件(打开or不打开)
  • 打开文件
    • 显式指定打开模式
  • 关闭文件
void fstreamTest(){string filename = "F:xxxxxx\\test.txt";// 创建一个文件流对象std::fstream fstrm(filename);// fstrm.open(filename);  也可以创建一个默认的fstream实例,用这种方式打开string line;// 是否成功打开与其关联的文件if(fstrm.is_open()){while(std::getline(fstrm, line)){std::cout<< line << std::endl;}}else{std::cerr<<"Flie is not open!"<<std::endl;}// 最后用完关闭fstrm.close();
}

string流

stringstream特有操作

操作说明
sstream strm一个未绑定的string流对象
sstream strm(s)创建一个string流对象,并保存string s的拷贝(该构造函数explicit)
strm.str()返回strm保存的string的拷贝
strm.str(s)将s拷贝到strm中。void类型

IO处理中常用的函数及操作符

getline(cin, str)

  • getline函数会从输入流中读取字符,直到遇到换行符或者指定分隔符位置,会将读取到的字符存储在str中
template <class charT, class traits, class Allocator>
std::basic_istream<charT,traits>& getline (std::basic_istream<charT,traits>& is, std::basic_string<charT,traits,Allocator>& str, charT delim);
  • is 是输入流,例如 std::cin
  • str 是要存储读取到的一行数据的字符串。
  • delim 是可选参数,用于指定行结束的分隔符,默认为换行符 \n

std::boolalpha

  • 使控制台在输入bool类型数据时,输出字符型的truefalse,而非0和1
  • 关闭使用:std::noboolalpha
void boolalphaTest(){std::cout<<"Default bool type: "<<true<<" "<<false<<'\n'<<std::boolalpha<<"use boolalpha: "<< true<<" "<<false<<'\n'<<std::noboolalpha<<"close boolalpha: "<< true<<" "<<false<<'\n';
}

image-20240429223253041

综合练习与demo

一、 创建文件并写入

	std::ofstream outFile;			// 创建写入文件流outFile.open("emptable1.txt"); 	// 创建该txt文件if (!outFile){std::cerr << "无法打开文件" << std::endl;return;}outFile << "on, ";				// 写入数据for (auto s : stepMap){outFile << s.second << ", ";}outFile << endl;outFile.close();				// 关闭文件

二、控制台输入数据并拆分存储

/*1、输入一行数据并按空格拆分*/
string input;
vector<string> latex;
cout << "Please input: ";
// 将一行输入存储到input中
std::getline(std::cin, input);		
// 创建istring流,并将input拷贝过去
std::istringstream iss(input);				
string str;
// istring流将通过空格进行拆分,传递赋值给str
while (iss >> str)							
{latex.push_back(str);
}/*2、输入多行数据并按行存储*/std::vector<std::string> lines;
std::string line;std::cout << "Enter multiple lines of text (enter an empty line to finish):" << std::endl;// 使用 getline 在循环中读取每一行输入
while (true) {std::getline(std::cin, line);if (line.empty()) {// 当输入为空行时,结束输入break;}lines.push_back(line);
}

三、读写电话簿

给定一个电话簿文件,里面格式大致为name number1 number2

读取该文件,并且存储人物及电话号码信息,存储时判断号码是否符合规定

将正确格式化后的字符,输出到结果文件中(结果文件包含title,不能覆盖)

image-20240429230735986

原始读取文件

image-20240429230808682

原始存储文件
#include <fstream>
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;struct PersonInfo
{/* data */string name;vector<string> phones;
};// 检查电话号码是否合法
bool checkNumber(string s)
{if (s.size() != 11 && (s.size() < 4 || s.substr(0, 4) != "0831")){return false;}else{for (auto &c : s){if (!isdigit(c) && c != '-'){return false;}}}return true;
}// 阅读最初的电话簿并存储
vector<PersonInfo> getOriginNumbers(string s)
{ifstream ifstm;// 文件输入流以默认模式打开文件ifstm.open(s);vector<PersonInfo> people;if (ifstm.is_open()){string line, number;// line以行存储文件中的内容while (getline(ifstm, line)){PersonInfo info;// 使用istringstream流时,record会根据空白符号对string进行拆分istringstream record(line);// 录入名字record >> info.name;// 录入多个号码while (record >> number){info.phones.push_back(number);}people.push_back(info);}}else{cerr << "Open file is faild! " << endl;}ifstm.close();return people;
}// 将正确的电话存储到电话簿中
void saveRightNumbers(vector<PersonInfo> &people, string s)
{ofstream ofs;// 以追加形式打开,避免覆盖文件中原有的内容ofs.open(s, ofstream::app);if (ofs.is_open()){for (const PersonInfo &p : people){ofs<<'\n';      // 先换行// 记录哪些电话号码有误ostringstream badNums;ofs << p.name<<"    ";for (const auto &number : p.phones){// 如果电话号码错误,存储到该string输出流中if (!checkNumber(number)){// 存储多个错误号码badNums << " " << number;}else{ofs<<number << "    ";}}if (!badNums.str().empty()){// 输出谁的电话号码有问题cerr << "[input error]  name: " << p.name<< ",  invalid number(s): " << badNums.str() << endl;}}}else{cerr << "Open savefile is faild! " << endl;}ofs.close();
}int main()
{string originfile = "F:\\xxxxxx\\numberDict.txt";string savefile = "F:\\xxxxxxx\\save.txt";vector<PersonInfo> people = getOriginNumbers(originfile);saveRightNumbers(people, savefile);return 0;
}

image-20240429231037247

控制台输出

image-20240429231057014

运行后的save文件

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

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

相关文章

android 抓取 logcat 日志的方法

1.找到这个路径 2.然后执行命令&#xff08;adb logcat -v time >.\\logcat.log&#xff09;&#xff0c;开始抓取日志 3.这个时候就可以去操作APP了&#xff0c;复现BUG了。 Ctrlc 结束日志抓取 adb logcat -c 清空旧日志

逆市创新高!水电“双雄“是怎样炼成的? 博通,赢麻了!

高分红夏季用电高峰AI的尽头是电力 6月7日&#xff0c;长江电力&#xff08;600900&#xff09;、华能水电&#xff08;600025&#xff09;股价双双上涨。截至收盘&#xff0c;长江电力股价上涨1%&#xff0c;收于28.31元/股&#xff1b;华能水电股价上涨1.52%&#xff0c;收于…

Matlab|遗传粒子群-混沌粒子群-基本粒子群

目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点&#xff08;重要的事情说三遍&#xff09;&#xff0c;对于采用智能算法的模型&#xff0c;可以采用算法改进的方式来达到提高整个文章创新水平的目的&…

基于STM32开发的智能机器人导航系统

目录 引言环境准备智能机器人导航系统基础代码实现&#xff1a;实现智能机器人导航系统 4.1 距离传感器数据读取4.2 电机控制4.3 实时路径规划与避障4.4 用户界面与状态显示应用场景&#xff1a;智能机器人导航与控制问题解决方案与优化收尾与总结 1. 引言 智能机器人导航系…

中国西部AI创新港,数字经济的新引擎

编辑&#xff1a;阿冒 设计&#xff1a;沐由 时间&#xff1a;2024年5月31日。 地点&#xff1a;西安交通大学创新港校区涵英楼千人报告厅。 人物&#xff1a;近千位政府、高校和企事业单位的代表&#xff0c;还有我。 我们的脚下&#xff0c;就是八百里秦川。 三秦自古多才俊。…

Linux基础指令(一)

前言 Linux基础指令主要学习&#xff1a;对目录、文件、压缩包、匹配查找&#xff0c;权限等操作 第一次接触ubuntu需要知道的基本知识 sudo passwd root 先给root用户设置密码 su root 切换到root用户 su zhangsan …

Django里的Form组件

Form组件提供 自动生成HTML标签和半自动读取关联数据 (“半自动”是指还得需要自己手写输入数据进来)表单验证和错误提示 要想创建并使用该组件&#xff0c;操作步骤如下&#xff1a; 在 views.py 里创建类 # 在 views.py 文件里from django import formsclass AssetForm(fo…

core dump核心转储

检查核心转储是否开启&#xff0c;否则无法生成core文件 ulimit -a 如果为0就需要修改 ulimit -c 10240 写一个会触发core命令的程序 以浮点数运算为例 #include <iostream>int main() {int i 1/0; } 在编译时使用-g选项 运行程序&#xff0c;生成core文件 gdb调试 g…

C++ MPI多进程并发

下载 用法 mpiexec -n 8 $PROCESS_COUNT x64\Debug\$TARGET.exe 多进程并发启动 mpiexec -f hosts.txt -n 3 $PROCESS_COUNT x64\Debug\$TARGET.exe 联机并发进程&#xff0c;其它联机电脑需在相同路径下有所有程序 //hosts.txt 192.168.86.16 192.168.86.123 192.168…

MySQL-备份(三)

备份作用&#xff1a;保证数据的安全和完整。 一 备份类别 类别物理备份 xtrabackup逻辑备份mysqldump对象数据库物理文件数据库对象&#xff08;如用户、表、存储过程等&#xff09;可移植性差&#xff0c;不能恢复到不同版本mysql对象级备份&#xff0c;可移植性强占用空间占…

java中集合List,Set,Queue,Map

Java SE中的集合框架是一组用于存储和操作对象的类和接口。它提供了丰富的数据结构&#xff0c;可以用于解决各种问题。Java SE中的集合框架包含以下主要类和接口&#xff1a; 一. Collection接口&#xff1a; 是集合框架的根接口&#xff0c;它定义了一些通用的集合操作方法…

【Modelground】个人AI产品MVP迭代平台(4)——Mediapipe视频处理网站介绍

文章目录 介绍模型配置输入输出核心实现&#xff08;源码&#xff09;总结 介绍 这篇文章我将硬核介绍Modelground的第一个产品——Mediapipe视频处理&#xff01;网站入口为https://tryiscool.space/ml-video/&#xff0c;如图所示&#xff0c;欢迎体验。 tip: 由于服务器带宽…

卡尔曼滤波器例子

卡尔曼滤波器 卡尔曼滤波器(Kalman Filter)是一种用于线性系统状态估计的递归算法,可以有效地融合传感器数据和系统模型来估计系统的状态。它在机器人学中广泛应用,尤其是位置和速度等状态的估计。通过卡尔曼滤波器,可以有效地估计机器人在二维平面内的真实位置,并减小测…

《经典图论算法》广度优先搜索

摘要&#xff1a; 1&#xff0c;广度优先搜索介绍 2&#xff0c;广度优先搜索的解题步骤 3&#xff0c;广度优先搜索的代码实现 1&#xff0c;广度优先搜索介绍 广度优先搜索(Breadth-first search&#xff0c;BFS)&#xff0c;又称宽度优先搜索&#xff0c;简单的说&#xff0…

把系统引导做到U盘,实现插上U盘才能开机

前言 有个小伙伴提出了这样一个问题&#xff1a;能不能把U盘制作成电脑开机的钥匙&#xff1f; 小白稍微思考了一下&#xff0c;便做了这样一个回复&#xff1a;可以。 至于为什么要思考一下&#xff0c;这样会显得我有认真思考他提出的问题。 Windows7或以上系统均支持UEF…

Flutter项目开发模版,开箱即用

前言 当前案例 Flutter SDK版本&#xff1a;3.22.2 每当我们开始一个新项目&#xff0c;都会 引入常用库、封装工具类&#xff0c;配置环境等等&#xff0c;我参考了一些文档&#xff0c;将这些内容整合、简单修改、二次封装&#xff0c;得到了一个开箱即用的Flutter开发模版…

memory动态内存管理学习之unique_ptr

此头文件是动态内存管理库的一部分。std::unique_ptr 是一种智能指针&#xff0c;它通过指针持有并管理另一对象&#xff0c;并在 unique_ptr 离开作用域时释放该对象。在发生下列两者之一时&#xff0c;用关联的删除器释放对象&#xff1a; 管理它的 unique_ptr 对象被销毁。…

YOLOv8 极简分割代码并输出各类别像素占比

文章目录 前言功能概述必要环境一、代码结构1. 参数定义2. 定义检测器类3. 计算各类别像素占比3.1 遍历每个检测到的目标3.2 获取当前目标的掩码和类别3.3 将掩码转换为整数多边形3.4 创建空白掩码图像并填充多边形3.5 计算掩码像素数3.6 计算掩码多边形的质心3.7 计算像素占比…

发光二极管十大品牌

日常电路设计中&#xff0c;LED是必用的元器件之一&#xff0c;辅助判定电路异常。 十大发光二极管品牌-LED灯珠生产厂家哪家好-LED发光二极管厂家前十-Maigoo品牌榜

Zabbix6.0自定义监控项

文章目录 一、自定义监控整体流程二、自定义监控案例1、监控TCP 443端口案例2、监控服务器异地登入(带参监控项) 一、自定义监控整体流程 操作端流程备注Agent端1️⃣ linux&#xff1a;通过命令、脚本取出对应的值2️⃣ linux&#xff1a;根据zbx要求按照格式、编写配置文件、…