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…...

Lecture 2 Text Preprocessing
目录 Some DefinitionsReasons for PreprocessingPreprocessing StepsSentence Segmentation 句子分割Binary Classifier 二元分类器Word Tokenization: English 英文词元标记化Word Tokenization: Chinese 中文词元标记化Word Tokenization: German 德语词元标记化Subword Tok…...

web练习第二周
前言:(博主个人学习笔记,不用看)web练习第二周,仅做出前3题。相比于第一周,难度大幅增加,写题时就算看了wp还是像个无头苍蝇一样到处乱创,大多都是陌生知识点,工具的使用…...

LC-1439. 有序矩阵中的第 k 个最小数组和(二分答案、多路归并)
1439. 有序矩阵中的第 k 个最小数组和 难度困难120 给你一个 m * n 的矩阵 mat,以及一个整数 k ,矩阵中的每一行都以非递减的顺序排列。 你可以从每一行中选出 1 个元素形成一个数组。返回所有可能数组中的第 k 个 最小 数组和。 示例 1:…...

一文1000字从0到1实现Jenkins+Allure+Pytest的持续集成
一、配置 allure 环境变量 1、下载 allure是一个命令行工具,可以去 github 下载最新版:https://github.com/allure-framework/allure2/releases 2、解压到本地 3、配置环境变量 复制路径如:F:\allure-2.13.7\bin 环境变量、Path、添加 F:\…...

给一个有序数组生成平衡搜索二叉树(java)
给一个有序数组生成平衡搜索二叉树 给一个有序数组生成平衡搜索二叉树递归生成二叉树专题 给一个有序数组生成平衡搜索二叉树 给定一个有序的数组,用这个数组生成一个平衡搜索二叉树. 这个题还是很简单的,知道什么时平衡搜索二叉树就行了, 左边值小于头节点值,头节点值小于右边…...

【JavaSE】Java基础语法(二十二):包装类
文章目录 1. 基本类型包装类2. Integer类3. 自动拆箱和自动装箱4. int和String类型的相互转换 1. 基本类型包装类 基本类型包装类的作用 将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据常用的操作之一:用于基本数据类型与字符串之间的…...

javascript基础十八:说说你对JavaScript中事件循环的理解
一、是什么 JavaScript 在设计之初便是单线程,即指程序运行时,只有一个线程存在,同一时间只能做一件事 为什么要这么设计,跟JavaScript的应用场景有关 JavaScript 初期作为一门浏览器脚本语言,通常用于操作 DOM &#…...

详解js中的浅拷贝与深拷贝
详解js中的浅拷贝与深拷贝 1、前言1.1 栈(stack)和堆(heap)1.2 基本数据类型和引用数据类型1.2.1 概念1.2.2 区别1.2.3 基本类型赋值方式1.2.4 引用类型赋值方式 2、浅拷贝2.1 概念2.2 常见的浅拷贝方法2.2.1 Object.assign()2.2.…...

Day9 敏捷测试——敏捷开发的特征、什么是敏捷测试?、极限编程、极限测试
Day9 敏捷测试——敏捷开发的特征、什么是敏捷测试?、极限编程、极限测试 文章目录 Day9 敏捷测试——敏捷开发的特征、什么是敏捷测试?、极限编程、极限测试敏捷开发的特征1、迭代式开发2、增量交付3、及时反馈4、持续集成5、自我管理敏捷开发和迭代式开发的根本区别1、性质…...

k8s 维护node与驱逐pod
1.维护node节点 设置节点状态为不可调度状态,执行以下命令后,节点状态会多出一个SchedulingDisabled的状态,即新建的pod不会往该节点上调度,本身存在node中的pod保持正常运行 kubectl cordon k8s-node01 kubectl get node 2.驱…...