c++输入输出文件操作stream
系列文章目录
C++ IO库
文章目录
- 系列文章目录
- 前言
- 一、文件IO
- 概述
- cout
- cin
- 其他istream类方法
- 文件输入和输出
- 内核格式化
- 总结
前言
一、文件IO
概述
c++程序把输入和输出看作字节流。输入时,程序从输入流中抽取字节:输出时,程序将字节流插入到输出流中。
一般输入和输出都有缓冲区。
C++程序通常在用户按下回车键时刷新输入缓冲区。
cin: 标准输入流
cout: 标准输出流
如果输出被重定向到文件,则标准错误流依然会被输出到屏幕
cerr: 标准错误流,无缓冲区
clog: 标准错误流,有缓冲区
cout
ostream类将输出转化为字符字节流
put() 显示字符
cout.put(‘W’).put(65.1);
write() 显示字符串
cout.write(“abcd”, 2).write(“ab”, 9);
long val = 234234; cout.write((char*)&val, sizeof(long));
将val内存中的数据作为字节字符输出到屏幕
输出缓冲区
输出缓冲区为512字节或为其整数倍
当输出为磁盘时有缓冲区,当输出为屏幕时会进行优化,也可显示指出刷新输出缓冲区:
cout << flush (刷新输出换出区) << endl(刷新输出换出区并插入换行符); flush(cout)也可
格式化
ostream插入运算符将输入转换成文本输出。
- 数字显示方式:dec, hex, oct
- 调整字段宽度:cout.width(x)
- 填充字符:cout.fill(‘*’)
- 设置浮点数的显示精度:cout.precision(2)
- 打印末尾的0和小数点
- cout.setf(ios_base::uppercase)
常量 含义 ios_base::boolalpha 输入和输出bool值,可以为true或false ios_base::showbase 对于输出,使用C++基数前缀(0, 0x) ios_base::showpoint 显示末尾的小数点 ios_base::uppercase 对于16进制输出,使用大写字母,E表示法 ios_base::showpos 在正数前加+ - 标准控制符:略
- 头文件iomanip
cin
cin 对象将标准输入表示为字节流。
对于如下代码:
int ele;
cin >> ele;
假设键入下面的字符:
-123Z
运算符将读取字符-123,因为它们都是整数的有效部分。但Z字符不是有效字符,因此输入中最后一个可接受的字符是3。Z将留在输入流中,下一个cin语句将从这里开始读取。与此同时,运算符将字符序列-123转换为一个整数值,并将它付给ele。
输入有时可能没有满足程序的期望。例如,假设输入的是Zcar,而不是-123Z。在这种情况下,抽取运算符将不会修改ele的值,并返回0(如果istream对象的错误状态被设置,if或while语句将判定该对象为false)。返回值false让程序能够检查输入是否满足要求。
while(cin >> num);
由于输入被缓冲。因此通过键盘输入的第二行在用户按下enter之前,不会被发送给程序。然而,循环在字符Z处停止了对输入的处理,因此它不与任何一种浮点格式匹配。输入与预期格式不匹配反过来将当导致表达式cin>>input的结果为false,因此while循环被终止。
成员 | 描述 |
---|---|
eofbit | 如果到达文件尾,则设置为1 |
badbit | 如果流被破坏,则设置为1:例如,文件读取错误 |
failbit | 如果输入操作未能读取预期的字符或输出操作没有写入预期的字符,则设置为1 |
goodbit | 另一种表示0的方法 |
good() | 如果流可以使用(所有的位都被清除),则返回true |
eof() | 如果eofbit被设置,则返回true |
bad() | 如果badbit被设置,则返回true |
fail() | 如果badbit或failbit被设置,则返回true |
rdstate() | 返回流状态 |
exceptions() | 返回一个位掩码,指出那些标记导致异常被引发 |
exceptions(isostate ex) | 设置那些状态将导致clear()引发异常:例如,如果ex是eofbit,则如果eofbit被设置,clear()将引发异常 |
clear(iostate s) | 将流状态设置为s:s的默认值为0(goodbit):如果(restate()& exceptions())!=0, 则引发异常 basic_ios::failure |
setstate(iostate s) | 调用clear(rdstate() | s)。这将设置与s中设置的为对应的流状态为,其他流状态为保持不变 |
其他istream类方法
int ct = 0;
char ch;
do{cin.get(ch);cout << ch;ct++;
}while(ch != '\n\);
cout << ct << endl;
// 若为下面的则跳过空格
int ct = 0;
char ch;
do{cin >> ch;cout << ch;ct++;
}while(ch != '\n\);
cout << ct << endl;
文件输入和输出
#include <fstream>ofstream fout("file.name"); // or f.open("xxx");
ifstream fin("file.name");char ch;
while(fin.get(ch)); // 一次读取一个字符,直到文件结尾,EOF
以默认模式打开文件进行输出将自动把文件的长度阶短为零,这相当于删除已有的内容
流状态
if(fin); // 打开成功为1,失败为0
if(fin.is_open()); // 可检查“文件模式”是否正确// 一次打开多个文件
ifstream fin;
fin.open("xxx1");
...
fin.close();
fin.clear();
fin.open("xxx2");
...
fin.close();
文件模式
常量 | 含义 |
---|---|
io_base::in | 打开文件,以便读取 |
io_base::out | 打开文件,以便写入 |
io_base::ate | 打开文件,并移到文件尾 |
ios_base::app | 追加到文件尾 |
ios_base::trunc | 如果文件存在,则截短文件 |
ios_base::binary | 二进制文件 |
ofstream.open("xxx", ios_base::out | ios_base::trunc);
ofstream.open("xxx", ios_base::out | ios_base::app);
- 文本格式
- 二进制文件
以二进制形式写读文件
ofstream fout("planets.dat", ios_base::out | ios_base::app | ios_base::binary);
fout.write( (char*)&pl, sizeof(pl));ifstream fin("planets.dat", ios_base::in | ios_base::binary);
fin.read((char*)&pl, sizeof(pl);
随机存取: 直接移动(不是依次移动)到文件的任何位置。随机存取常被用于数据库文件,程序维护一个独立的索引文件,该文件指出数据在主数据文件中的位置。
fstream类从iostream类派生,后者基于istream和ostream连个类,因此它继承了它们的方法。它还继承了两个缓冲区,一个用于输入,一个用于输出,并能同步化这两个缓冲区的处理。也就是说当程序读写文件时,它将协调地移动输入缓冲区中的输入指针和输出缓冲区中的输出指针。
读写模式:
finout.open(file, ios_base::in | ios_base::out | ios_base::binary);
seekp ofstream
seekg ifstream
seekp()用于将输出指针移到指定的文件位置。seekg(),原型:
basic_istream<charT, traits>& seekg(off_type, ios_base::seekdir);
basic_istream<charT, traits>& seekg(pos_type);
equal to:
istream& seekg(streamoff, ios_base::seekdir);
istream& seekg(streampos);
第一个原型定位到离第二个参数指定的文件位置特定距离的位置,第二个原型定位到离文件开头特定距离的位置。
assume fin is a ifstream object:
fin.seekg(30, ios_base::beg); // 30 bytes beyond the beginning
fin.seekg(-1, ios_base::cur); // back up one byte
fin.seekg(0, ios_base::end); // go to the end of the file
将streampos位置看作相对文件开始处的位置(第一个字节编号为0),偏移量
fin.seekg(112);
如果要检查文件指针的当前位置,则对于输入流,可以使用tellg()方法,对于输出流,可以使用tellp()方法,它们返回streampos。fstream对象的输入输出指针同步。如果使用istream ostream对象则输入输出指针不同步。
打开文件、移到文件开头并显示文件内容:
fstream finout; // read and write streams
finout.open(file, ios::in | ios::out | ios::binary);
// note: some unix systems require omitting | ios::binary
int ct = 0;
if (finout.is_open()) {finout.seekg(0); // go to beginningcout << "Here" << file << "file:\n";while(finout.read((char*)&pl, sizeof(pl)){cout << ct++ << ": " << setw(LIM) << pl.name << ": "<< setprecision(0) << setw(12) << pl.population<< setprecision(2) << setw(6) << pl.g << endl;}if (finout.eof()) { // 读取到文件尾finout.clear(); // clear eof flag} else { // 没有读到文件尾,而是其他故障导致cerr << "Error in reading" << file << ".\n";exit(EXIT_FAILURE);}
} else { // 若文件打开失败cerr << file << " could not be opened.\n";exit(EXIT_FAILURE);
}cout << "Enter the record number you wish to change: ";
long rec;
cin >> rec;
eatline(); // get rid of newline
if (rec < 0 || rec >= ct) {cerr << "Invalid record number.\n";exit(EXIT_FAILURE);
}
streampos place = rec * sizeof pl; // convert to streampos type
finout.seekg(place); // random access
finout.read((char*)&pl, sizeof pl);
cout << "Your selec:\n";
cout << rec << ": " << setw(LIM) << pl.name << ": "<< setprecision(0) << setw(12) << pl.population<< setprecision(2) << setw(6) << pl.g << endl;
if (finout.eof()) finout.clear();
cout << "Enter planet name: ";
cin.get(pl.name, LIM);
eatline();
cout << "Enter population: ";
cin >> pl.population;
cout << "Enter planet's acceleration of gravity: ";
cin >> pl.g;
finout.seekp(place);
finout.write((char*)&pl, sizeof pl) << flush; // 刷新输出if (finout.fail()){cerr << "Error on attempted write\n";exit(EXIT_FAILURE);
}
stdio stddef stdlib unistd
使用临时文件
#include
char* tmpnam(char* pszName);
生成临时文件名
tmpnam()函数创建一个临时文件名,将它放在pszName指向的C-风格字符串中。常量L_tmpnam和TMP_MAX (二者都是在cstdio中定义的)限制了文件名包含的字符数以及在确保当前目录中不生成重复文件名的情况下可被调用的最多次数
内核格式化
iostream族支持程序与中断之间的I/O,而fstream族使用相同的接口提供程序和文件之间的I/O。C++库还提供了sstream族,它们使用相同的接口提供程序和string对象之间的I/O。也就是说,可以使用于cout 的ostream方法将格式化信息写入到string对象中,并使用istream方法(如getline())来读取string对象中的信息。读取string对象中格式化信息或将格式化信息写入到string对象中被称为内核格式化(incore formatting)。
#include <iostream>
#include <sstream>
#include <string>int main()
{using namespace std;ostringstream outstr; // manages a string streamstring hdisk;cout << "What's the name of your hard disk? ";getline(cin, hdisk); // getlineint cap;cout << "What's its capacity in GB? ";cin >> cap;// write formatted information to string streamoutstr << "The hard disk " << hdisk << " has a capacity of "<< cap << " gigabytes.\n";string result = outstr.str(); // save resultcout << result; // show contents
}
...
string lit = "it was a dark and storm day";
istringstream instr(lit); // use buf for input
string word;
while(instr >> word)cout << word << endl;
总结
get() 单字符输入
getline() 字符串输入
seekg()和seekp()函数提供对文件的随机存取。这些类方法使得能够将文件指针放置到相对于文件开头、文件尾和当前位置的某个位置。tellg()和tellp()方法报告当前的文件位置。
获取文件大小
ifstream fin("planets.dat", ios::in | ios::binary);
fin.seekg(0, ios::end);
unsigned long long pos = fin.tellg();
cout << pos << endl;
random.cpp
#include <iostream>
#include <fstream>
#include <iomanip> // 格式化输出
#include <cstdlib> // for exitusing namespace std;const int LIM = 20;struct planet
{char name[LIM];double population;double g;
};const char* file = "planets.dat";
inline void eatline()
{while (cin.get() != '\n');
}int main()
{planet pl;cout << fixed;fstream finout;finout.open(file, ios::in | ios::out | ios::binary);int cnt = 0;if (finout.is_open()) {finout.seekg(0); // go to beginningcout << "Here, contents " << file << " file:\n";while (finout.read((char*)&pl, sizeof pl)) {cout << cnt++ << ": " << setw(LIM) << pl.name << ": "<< setprecision(0) << setw(12) << pl.population<< setprecision(2) << setw(6) << pl.g << endl;}if (finout.eof()) {finout.clear();} else {cerr << "Error in reading " << file << ".\n";exit(EXIT_FAILURE);}} else {cerr << file << " could not be opened.\n";exit(EXIT_FAILURE);}// change a recordcout << "Enter the record number you wish to change: ";long rec;cin >> rec;eatline();if (rec < 0 || rec >= cnt) {cerr << "Invalid record number.\n";exit(EXIT_FAILURE);}streampos place = rec * sizeof pl;finout.seekg(place);if (finout.fail()) {cerr << "Error on attempted seek\n";exit(EXIT_FAILURE);}finout.read((char*)&pl, sizeof pl);cout << "Your selection:\n";cout << rec << ": " << setw(LIM) << pl.name << ": "<< setprecision(0) << setw(12) << pl.population<< setprecision(2) << setw(6) << pl.g << endl;if (finout.eof()) {finout.clear();}cout << "Enter name: ";cin.get(pl.name, LIM);eatline();cout << "Enter popu: ";cin >> pl.population;cout << "Enter g: ";cin >> pl.g;finout.seekp(place);finout.write((char*)&pl, sizeof pl) << flush;if (finout.fail()) {cerr << "Error\n";exit(EXIT_FAILURE);}// show revised filecnt = 0;finout.seekg(0); // goto beginning of filecout << "Here " << file << " file:\n";while (finout.read((char*)&pl, sizeof pl)) {cout << cnt++ << ": " << setw(LIM) << pl.name << ": "<< setprecision(0) << setw(12) << pl.population<< setprecision(2) << setw(6) << pl.g << endl;}finout.close();cout << "Done.\n";
}
writedat.cpp
#include <iostream>
#include <fstream>
#include <iomanip> // 格式化输出
#include <cstdlib> // for exitconst int LIM = 20;struct planet
{char name[LIM];double population;double g;
};int main()
{using namespace std;ofstream fout("planets.dat", ios::out | ios::binary);if (!fout) {return 0;}planet p1 = {"earth", 1000, 9.80001};planet p2 = {"mars", 34234, 4.555};planet p3 = {"moon", 45, 3.55};fout.seekp(0);fout.write((char*)&p1, sizeof p1);fout.write((char*)&p2, sizeof p2);fout.write((char*)&p3, sizeof p3);fout.close();}
相关文章:

c++输入输出文件操作stream
系列文章目录 C IO库 文章目录 系列文章目录前言一、文件IO概述coutcin其他istream类方法 文件输入和输出内核格式化总结 前言 一、文件IO 概述 c程序把输入和输出看作字节流。输入时,程序从输入流中抽取字节:输出时,程序将字节流插入到输…...

【小呆的力学笔记】非线性有限元的初步认识【三】
文章目录 1.2.2 基于最小势能原理的线性有限元一般格式1.2.2.1 离散化1.2.2.2 位移插值1.2.2.3 单元应变1.2.2.4 单元应力1.2.2.5 单元刚度矩阵1.2.2.6 整体刚度矩阵1.2.2.7 处理约束1.2.2.8 求解节点载荷列阵1.2.2.9 求解位移列阵1.2.2.10 计算应力矩阵等 1.2.2 基于最小势能原…...
python计算闰年
这里说明一下:看到网上很多写python计算闰年的,有很多是不同。 有份省级期刊万年历计算公元1-10000年的闰年 算法如下:4000年停闰一次。区别其他算法,有些是3200年停闰一次。 def division(dividend, divisor) -> bool:"…...
聊聊如何使用Js写一个简单的二级联动和三级联动呢?
前言:咳咳哈,大佬说:"这不是有手就行了?"好吧,这里不做过多罗里吧嗦,真的不过多吹,我们在下面直接上代码上注释。 文章目录: 原Js二级联动实现原Js三级联动实现 一、二级…...

IPv4 和 IPv6 的特点、区别以及在互联网中的应用
在当今互联网时代,IP 地址是连接和通信的基础。IPv4(Internet Protocol version 4)和 IPv6(Internet Protocol version 6)是两种常见的 IP 地址版本。IPv4 是最早广泛使用的 IP 地址协议,而 IPv6 则是 IPv4…...

JavaScript处理移动web交互
touch对象和touchevent touch事件 touch对象 每一次发生touch事件时就会产生一个touch对象,类似事件处理函数中的事件对象。 <div class" "><button class"child" style"height: 400px; width: 400px">我是按钮</b…...

4年测试经验,一问三不知,过于离谱...
公司今年要招人,面倒是面了很多测试,但没有一个合适的。一开始想要的就是中级的水准,也没指望来大牛,当然来了更好,提供的薪资在10-20k,来面试的人有很多,但平均水准真的是让人失望。 看简历时很多都写着3…...
Java 与查找算法(2)二分查找
一、二分查找 二分查找,也称折半查找,是一种常见的查找算法。它的思想是将有序数组分成两部分,取中间位置的值与目标值进行比较,如果相等则返回该位置,如果目标值小于中间值,则在左半部分继续查找…...
Java程序设计入门教程--原始类与包装类
包装类 Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便。 为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统…...

pip安装python库速度慢、失败及超时报错解决办法
背景: 随着人工智能的不断兴起,python作为最接近人工智能的语言,变得越来越流行,人生苦短,python要学起来。之所以越来用的人喜欢学习python和研究Python,除了python本身便于学些、语法简短、面向对象等特点…...
向量数据库
向量数据库可以做哪些事情 存储和索引向量检索相似向量,还具有过滤功能自动将文档转变成向量,所以会自动化分词、向量化、索引等操作 目前存在的向量数据库: 名称github开源协议chromahttps://github.com/chroma-core/chromaApache 2.0Mil…...

leetcode 11.盛最多水的容器
题目描述 跳转到leetocde题目 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明ÿ…...

都说00后已经躺平了,但是有一说一,该卷的还是卷啊。
这不,三月份春招我们公司来了个00后,工作没两年,跳槽到我们公司起薪20K,都快接近我了。 后来才知道人家是个卷王,从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天,原来这位小老弟家里条件不太好&…...
牛客网刷题学习SQL(二)
SQL22 统计每个学校的答过题的用户的平均答题数 描述 运营想要了解每个学校答过题的用户平均答题数量情况,请你取出数据。 用户信息表 user_profile,其中device_id指终端编号(认为每个用户有唯一的一个终端),gender指…...
深蓝学院 C++笔记 先导篇章 - 绪论
一、介绍-老师寄语 为什么选择C? 高性能解决问题 二、C推荐书目 1. 基础 《C Primer》,Stanley B. Lippman 等著,王刚、杨巨峰等译 2. 进阶 《Effective C》,Scott Meyers 著,侯捷译。 《More Effective C》&am…...
R7-19 天梯赛团队总分
“天梯赛”的竞赛题目一共有 15 道,分为 3 个梯级: 基础级设 8 道题,其中 5 分、10 分、15 分、20 分的题各 2 道,满分为 100 分;题目编号相应为L1-X,X取1,2,3,4,5,6,7,8,分别表示基础级的8道题…...

使用 Kotlin 的 Opt-in (选择加入)功能注解API提示当前非稳定API
前言 之前在给公司项目封装库的时候,领导告诉我封装的漂亮一点,等以后公司发展起来了可能需要把这个库提供给第三方接入使用。 此时,就有这么一个问题:某些功能函数使用条件比较苛刻,直接使用可能会出现意想不到的后…...

webpack配置排除打包
webpack配置排除打包 思路 打包时,不要把类似于element-ui第三方的这些包打进来 从网络上,通过url地址直接引入这些包 操作 (1)先找到 vue.config.js, 添加 externals 项,具体如下: config…...

HNU-操作系统OS-ucoreLab系列-感悟
谨以此片篇,献给熬夜的8个晚上,以及逝去的时光。 感悟: 今天结束了所有的Lab实验(2023.6.3),感慨万千。 喜是这个实验终于结束了,悲是其实有好多地方我都没有理解。 应该指出,由于验收的助教学长学姐们的宽容,HNU实际上在验收这一块的要求还是比较低的。 但是这个…...

MySQL运维篇(三)
五.读写分离 5.1 介绍 读写分离,简单地说是把对数据库的读和写操作分开,以对应不同的数据库服务器。主数据库提供写操作,从数据库提供读操作,这样能有效地减轻单台数据库的压力。 通过MyCat即可轻易实现上述功能,不仅可以支持MySQL&#x…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...