【C++】<知识点> 标准和文件的输入输出

目录

        一、输入输出操作

                1. 相关的类

                2. 标准流对象

                3. istream类的成员函数

二、流操纵算子

        1. 整数流的基数

        2. 浮点数精度的流操纵算子

        3. 域宽的流操纵算子

        4. 其他的流操纵算子

        5. 用户自定义流操纵算子

三、文件读写

        1. 文本文件的读写

        2. 二进制文件的读写

        3. 文件读写指针

        4. 文本文件和二进制文件区别


一、输入输出操作

1. 相关的类

  • ios基类派生出istream和ostream。
  • istream派生出ifstream,ostream派生出ofstream。
  • iostream继承自istream和ostream。
  • fstream继承自iostream。

注意:cin就是istream类的对象,cout就是istream类的对象。

2. 标准流对象

(1) 输入流对象:cin与标准输入设备相连(从键盘获取数据)。也可以被重定向为从文件中读取数据。

(2) 输出流对象:

  • cout与标准输出设备相连(在屏幕上打印数据)。也可以被重定向为向文件写入数据(freopen函数)。
  • cerr与标准错误输出设备相连。
  • clog与标准错误输出设备相连。
  • cerr和clog的区别在于cerr不使用缓冲区,直接向显示器输出信息;而clog采用缓冲区,只有缓冲区满或者刷新时才会输出到屏幕上。

(3) 代码示例:

【1】输出重定向

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;int main()
{double x, y;cin >> x >> y;//freopen函数:输出重定向到文件//原型:FILE *freopen(const char *path, const char *mode, FILE * stream);//path是目标文件//mode为文件打开模式"r"或"w"//stream为标准流文件,例如stdin标准输入流, stdout标准输出流, stderr标准错误流freopen("cout.txt", "w", stdout);if (y == 0) {cerr << "error!" << endl;}else {cout << x / y;//输出到文件cout.txt中}return 0;
}

  

显然,屏幕上并没有输出计算结果0.5,该结果输出到cout.txt文件中。

【2】输入重定向

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;int main()
{int n1 = 0, n2 = 0;//freopen函数:输入重定向freopen("input.txt", "r", stdin);cin >> n1 >> n2;//由于重定向了,不会在终端等用户输入cout << "结果:" << n1 << ", " << n2 << endl;return 0;
}

【3】判断输入流结束

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;int main()
{int x;freopen("test.txt", "r", stdin);while (cin >> x) {cout << "读入:" << x << endl;}return 0;
}

注意:①这里将cin重定向为从文件读取数据,那么读到文件末尾即结束。若未重定向,从键盘中输入则需要单独一行输入Ctrl+Z代表输入流结束。cin >> x返回值为istream&,而istream会有对象的重载,将其转换成bool类型,因此可以作为循环条件。

3. istream类的成员函数

(1) getline函数:

  • 原型:①istream& getline(char* buf, int bufSize); ②istream& getline(char* buf, int bufSize, char delim);
  • 对于第一个原型:从输入流中读取bufSize-1个字符到缓冲区buf,或读到'\n'为止(哪个先到算哪个)。
  • 对于第二个原型:从输入流中读取bufSize-1个字符到缓冲区buf,或读到delim字符为止(哪个先到算哪个)。
  •  注意:
    • 两个函数都会自动在buf中读入数据的结尾添加'\0'。
    • ‘\0’和delim都不会被读入buf,但会被输入流中取走。
    • 如果输入流中'\n'或delim之前的字符个数达到或超过了bufSize个,就导致读入错误,即虽然本次读入已经完成,但是之后的读入就都失败了。
    • 可以用if (!cin.getline(...))判断输入是否结束。

(2) bool eof(); 用于判断输入流是否结束。

(3) int peek(); 返回下一个字符,但不从流中去除。

(4) istream& putback(char c); 将字符ch放回输入流的头部。

(5) istream& ignore(int nCount = 1, int delim = EOF); 从流中删掉最多nCount个字符,遇到EOF结束。

(6) getline函数代码示例:

#include <iostream>
using namespace std;int main()
{int x;char buf[90];cin >> x;cin.getline(buf, 90, '\n');cout << buf << endl;return 0;
}


二、流操纵算子

1. 整数流的基数

(1) 说明:在cout时,可以指定输出的整数的进制:dec(十进制)、oct(八进制)、hex(十六进制)。

(2) 注意:①使用流操纵算子,需要添加头文件iomanip。②一旦设置,就会持续有效直到新的操纵算子出现。

(3) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
using namespace std;int main()
{int n = 10;cout << dec << n << endl;//十进制显示ncout << oct << n << endl;//八进制显示ncout << hex << n << endl;//十六进制显示n//一旦设置dec、oct或者hex,就会持续有效直到写新操纵算子。cout << n << endl;return 0;
}

2. 浮点数精度的流操纵算子

(1) precision:是ostream的成员函数,调用方式为:cout.precision(5); 用于指定浮点数的有效位数(非定点方式)系统默认是非定点方式。

(2) setprecision:流操纵算子,调用方式为:cout << setprecision(5); 用于指定浮点数的有效位数(非定点方式)和指定浮点数的小数后的有效位数(非定点方式)定点方式:小数点必须出现在个位数后面。

(3) 注意:

  • 当位数超过精度时会四舍五入。
  • setprecision方式会持续有效,直到设置新的精确度。
  • setprecision操纵算子也需要添加头文件iomanip。
  • 在非定点方式下,setprecision可能会使用科学计数法来表示。

(4) setiosflags(ios::fixed):以小数点位置固定的方式来输出(可以简单用cout << fixed;)。另外,cout << scientific表示采用科学计数法。

(5) resetiosflags(ios::fixed):取消以小数点位置固定的方式来输出。

(6) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
using namespace std;int main()
{float f = 1234567.89;int n = 123456;//默认是非定点方式cout << "*****非定点******" << endl;cout << setprecision(6);//设置浮点数有效位数为6cout << f << endl;//由于非定点方式且规定只能有6位,因此用科学计数法显示cout << n << endl;//浮点数的操纵算子不影响整数//修改为定点方式cout << "*****定点********" << endl;cout << setiosflags(ios::fixed);cout << f << endl;//小数点后有6位,不够就补0//修改为非定点方式cout << "*****非定点******" << endl;cout << resetiosflags(ios::fixed);cout << f << endl;//由于非定点方式且规定只能有6位,因此用科学计数法显示return 0;
}

3. 域宽的流操纵算子

(1) setw:流操纵算子,用于设置域宽。调用方式:cout << setw(5)或cin >> setw(5)。

(2) width:成员函数,用于设置域宽。调用方式:cout.width(5)或cin.width(5)。

(3) 注意:域宽的流操纵算子是一次性的,每次输入输出前都需要指定宽度。

(4) 代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
using namespace std;int main()
{int m = 4;char string[10];cin >> setw(5);//设置输入宽度while (cin >> string) {cout << setw(m++);//设置输出宽度cout << string << endl;cin >> setw(5);}return 0;
}

(5) 结果解释:

  • 第一行是我们输入的数据1234567890.
  • 第二行输出1234。首先,设置输入宽度为5(实际上只接收4个字符,最后自动加'\0'),那么string里就是1234‘\0’。其次,设置输出宽度为4(设置完后m自增为5),那么输出4个字符即1234.
  • 第三行输出" 5678"。首先,设置输入宽度为5(实际上只接收4个字符,最后自动加'\0'),那么string里就是5678‘\0’。其次,设置输出宽度为5(设置完后m自增为6),那么输出5个字符即空格+5678.
  • 第四行输出"    90"。首先,设置输入宽度为5(实际上只接收4个字符,最后自动加'\0'),那么string里就是90‘\0’。其次,设置输出宽度为6(设置完后m自增为7),那么输出6个字符即4个空格+90.

4. 其他的流操纵算子

(1) cout << showpos; 非负数显示正号。

(2) cout << noshowpos; 非负数不显示正号。

(3) cout << setfill(*); 宽度不足用*填补。

(4) cout << right; 右对齐,宽度不足则左边填充。

(5) cout << left; 左对齐,宽度不足则右边填充。

(6) cout << internal; 在负号和数字之间填充。

(7) 综合案例:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
using namespace std;int main()
{int i = 141;double x = 1234567.89, y = 12.34567;//1) 8d 141 215cout << "1) " << hex << i << " " << dec << i << " " << oct << i << endl;//2) 1.2346e+006 12.346cout << "2) " << setprecision(5) << x << " " << y << endl;//3) 1234567.89000 12.34567cout << "3) " << fixed << setprecision(5) << x << " " << y << endl;//4) 1.23457e+006 1.23457e+001cout << "4) " << scientific << setprecision(5) << x << " " << y << endl;//5) ***+12.10000cout << "5) " << showpos << right << fixed << setprecision(5) << setfill('*') << setw(12) << 12.1 << endl;//6) 12.10000****cout << "6) " << noshowpos << left << fixed << setprecision(5) << setfill('*') << setw(12) << 12.1 << endl;//7) ****12.10000cout << "7) " << noshowpos << right << fixed << setprecision(5) << setfill('*') << setw(12) << 12.1 << endl;//8) -***12.10000cout << "8) " << showpos << right << fixed << setprecision(5) << internal << setfill('*') << setw(12) << -12.1 << endl;//9) 12.10000cout << "9) " << noshowpos << fixed << setprecision(5) << 12.1 << endl;return 0;
}

5. 用户自定义流操纵算子

(1) 格式:

ostream& 函数名(ostream& cout) {//执行的操作return cout;
}

(2) 代码示例:定义tab流操纵算子。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;ostream& tab(ostream& output) {return output << '\t';
}int main()
{cout << "a" << tab << "b" << endl;return 0;
}

(3) 底层解释:由于iostream里对<<进行了重载(使用成员函数方式),即ostream& operator << (ostream& (*p) (ostream&)); 其中ostream& (*p) (ostream&)是函数指针,能够根据函数名找到对应的函数并执行函数体,同时内部还返回了*this就是对象本身。因此,在上述示例中,tab就是一个函数名,会执行tab的函数体。


三、文件读写

1. 文本文件的读写

(1) 创建读文件对象:ifstream srcFile("in.txt", ios::in);

(2) 创建写文件对象:ofstream destFile("out.txt", ios::out);

(3) 从文件中读取字符:srcFile >> x;

(4) 将字符写入文件:destFile << x;

(5) 注意:

  • 写文件对象中ios::out选项:删除原有内容,写入新内容。
  • 写文件对象中ios::app选项:在原内容后面追加新内容。
  • 读写文件对象中ios::binary选项:以二进制方式写入/读取。
  • ifstream和ofstream换成fstream也行。

(6) 代码示例:将in.txt中的内容1 234 9 45 6 879排序,并存到out.txt中。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;int main()
{//1.打开文件in.txtifstream srcFile("./in.txt", ios::in);if (!srcFile) {cout << "srcFile文件打开失败!" << endl;return -1;}//2.读取文本字符并加入vector中int readInt;vector<int> v;while (srcFile >> readInt) {v.push_back(readInt);}//3.对vector中元素排序sort(v.begin(), v.end());//4.将排序结果写入out.txtofstream outFile("./out.txt", ios::out);if (!outFile) {cout << "outFile文件打开失败!" << endl;return -1;}for (int i = 0; i < v.size(); i++) {outFile << v[i] << " ";}//5.关闭文件srcFile.close();outFile.close();return 0;
}

         

2. 二进制文件的读写

(1) 创建读写对象:方式与文本文件相同,但是选项要或(|)上ios::binary选项!

(2) 读文件:使用ifstream和fstream中的成员函数read函数。

  • 函数原型:istream& read(char* s, long n);
  • 功能:将文件读指针指向的地方的n个字节内容,读取到内存地址s,然后读指针向后移动n字节。

(3) 写文件:使用ofstream和fstream中的成员函数write函数。

  • 函数原型:istream& write(const char* s, long n);
  • 功能:将内存地址s处的n个字节内容,写入到写指针指向的位置,然后写指针向后移动n字节。

(4) 代码示例:将整数120写入二进制文件,再从该二进制文件中读取整数。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;int main()
{//写入ret于二进制文件out.dat中int ret = 120;ofstream outFile("./out.dat", ios::out | ios::binary);outFile.write((const char*)(&ret), sizeof(int));outFile.close();//从out.dat中读取一个整数int readInt;ifstream inFile("./out.dat", ios::in | ios::binary);inFile.read((char*)(&readInt), sizeof(int));inFile.close();//显示读取的整数cout << readInt << endl;return 0;
}

3. 文件读写指针

(1) 介绍:

  • 对于输入文件,有一个读指针。
  • 对于输出文件,有一个写指针。
  • 对于输入输出文件,有一个读写指针。
  • 读/写指针标识文件操作的当前位置。

(2) 读指针相关操作:

  • tellg():获取读指针的位置。调用方式:"输出对象.tellg()"。
  • seekg(int i):移动读指针至第i个字节处。调用方式:"输出对象.seekg(i)"。
  • seekg(int i, ios::beg):移动至距文件开始的第i个位置。
  • seekg(int i, ios::cur):移动至当前位置后的第i位置。
  • seekg(int i, ios::end):移动至距文件末尾的第i个位置。(常用于统计文本的字符数)

(3) 写指针相关操作:

  • tellp():获取写指针的位置。调用方式:"输出对象.tellp()"。
  • seekp(int i):移动写指针至第i个字节处。调用方式:"输出对象.seekp(i)"。
  • seekp(int i, ios::beg):移动至距文件开始的第i个位置。
  • seekp(int i, ios::cur):移动至当前位置后的第i位置。
  • seekp(int i, ios::end):移动至距文件末尾的第i个位置。

(4) 代码示例:输出A~Z于test.txt中,并且每两个字符间空两格。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using namespace std;int main()
{ofstream outFile("./test.txt", ios::out);/* 输出A~Z于test.txt中,并且每两个字符间空两格*/for (char i = 'A'; i <= 'Z'; i++) {//获取写文件指针位置int location = outFile.tellp();//写入字符outFile << i;//文件指针会自动+1,再使用seekp跳到后两个位置outFile.seekp(2, ios::cur);//打印测试信息cout << location << endl;}//关闭文件outFile.close();return 0;
}

4. 文本文件和二进制文件区别

(1) 不同操作系统下换行符号区别:

  • Linux下的换行:'\n'(ASCII:0x0a)
  • Windows下的换行:'\r\n'(ASCII:0x0d0a)
  • MacOS下的换行:'\r'(ASCII:0x0d)
  • 由于ASCII码不同,Linux和MacOS的文本文件在Windows中的记事本打开时不换行。

(2) 文本文件和二进制文件区别:

  • Linux下打开文件,用不用ios::binary没区别。
  • Windows下打开文件,如果不用ios::binary,则会造成①读取文件时,所有的'\r\n'都会被当作'\n'处理,因此会少读了一个字符'\r'。②写入文件时,写入单独的'\n'时,系统会自动加'\r',因此多写了一个字符'\r'。
  • 一般来说,使用二进制文件更加节省空间。例如,保存123456,若保存于文本文件则需要6个字节,而保存于二进制文件用一个int的字节就行了。

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

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

相关文章

vue 点击复制文本到剪贴板

一、首先在vue文件的template中定义复制按钮 <div size"small" v-if"item.prop jadeCode" class"cell-container"><span>{{ scope.row.jadeCode }}</span> <button click"handleCopy(scope.row.jadeCode)" clas…

K8s是如何Watch的?

1. 概述 进入 K8s 的世界&#xff0c;会发现几乎所有对象都被抽象为了资源(Resource)&#xff0c;包括 K8s Core Resources(Pod, Service, Namespace 等)、CRD、APIService 扩展的资源类型。同时 K8s 底层将这些资源统一抽象为了 RESTful 的存储(Storage)&#xff0c;一方面服…

jellyfish安装及使用(Bioinformatics工具-020)

01 背景 基因组survey以测序技术为基础&#xff0c;基于小片段文库的低深度测序&#xff0c;通过K-mer分析&#xff0c;快速获得基因组大小、杂合度、重复序列比例等基本信息&#xff0c;为制定该物种的全基因组de novo测序策略提供有效依据。 jellyfish (水母) 是一个用于快…

Docker-镜像迁移的三种方式=>备份恢复公有仓库私有仓库

制作好的镜像要被别人使用&#xff0c;有三种方式&#xff1a; 1.先备份镜像&#xff0c;别人通过u盘或者其它方式拷贝后&#xff0c;再恢复镜像&#xff0c;这种方式比较麻烦 2.将制作的镜像上传到公共镜像仓库&#xff0c;被别人拉取后使用&#xff0c;但可能存在网络不通畅或…

【零基础C语言】内存函数

前言&#xff1a; 我们之前学过strcpy&#xff0c;strcmp等等函数&#xff0c;他们可以拷贝字符串和比较字符串等等&#xff0c;那么有没有什么函数不光可以拷贝字符串还可以拷贝其他的数据呢&#xff0c;答案就是内存函数。 相较于字符串函数&#xff0c;内存函数可以拷贝的…

赎金信[简单]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你两个字符串&#xff1a;ransomNote和magazine&#xff0c;判断ransomNote能不能由magazine里面的字符构成。如果可以&#xff0c;返回true&#xff1b;否则返回false。magazine中的每个字符只能在ransomNote中使用一次。 示例 …

DPDK实践之(1)dpdk基础使用

DPDK实践之(1)dpdk基础使用 Author: Once Day Date: 2024年5月19日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;Linux基础知识_Once…

C语言 | Leetcode C语言题解之第109题有序链表转换二叉搜索树

题目&#xff1a; 题解&#xff1a; int getLength(struct ListNode* head) {int ret 0;while (head ! NULL) {ret, head head->next;}return ret; }struct TreeNode* buildTree(struct ListNode** head, int left, int right) {if (left > right) {return NULL;}int …

Mac维护神器CleanMyMac X成为你的苹果电脑得力助手

在数字化时代&#xff0c;Mac电脑已成为众多用户的首选。然而&#xff0c;随着频繁的使用和数据量的日益增长&#xff0c;许多Mac用户面临着系统杂乱、存储空间不足以及隐私保护等问题。幸运的是&#xff0c;"CleanMyMac X"这款优化和清理工具应运而生&#xff0c;它…

ROCm上情感分析:使用循环神经网络

15.2. 情感分析&#xff1a;使用循环神经网络 — 动手学深度学习 2.0.0 documentation (d2l.ai) 代码 import torch from torch import nn from d2l import torch as d2lbatch_size 64 train_iter, test_iter, vocab d2l.load_data_imdb(batch_size)class BiRNN(nn.Module):…

java抽象类,接口,枚举练习题

第一题&#xff1a; 答案&#xff1a; class Animal{//成员变量protected String name;protected int weight;//构造方法public Animal(){this.name"refer";this.weight50;}public Animal(String name,int weight){this.namename;this.weightweight;}//成员方法publ…

Bugku Crypto 部分题目简单题解(四)

目录 python_jail 简单的rsa 托马斯.杰斐逊 这不是md5 进制转换 affine Crack it rsa python_jail 启动场景 使用虚拟机nc进行连接 输入print(flag) 发现报错&#xff0c;经过测试只能传入10个字符多了就会报错 利用python中help()函数&#xff0c;借报错信息带出flag变…

【力扣刷题笔记第三期】Python 数据结构与算法

先从简单的题型开始刷起&#xff0c;一起加油啊&#xff01;&#xff01; 点个关注和收藏呗&#xff0c;一起刷题鸭&#xff01;&#xff01; 第一批题目 1.设备编号 给定一个设备编号区间[start, end]&#xff0c;包含4或18的编号都不能使用&#xff0c;如&#xff1a;418、…

java抽象类和接口知识总结

一.抽象类 1.啥是抽象类 用专业语言描述就是&#xff1a;如果一个类中没有包含足够的信息来描绘一个具体的对象&#xff0c;这样的类就是抽象类 当然这话说的也很抽象&#xff0c;所以我们来用人话来解释一下抽象类 抛开编程语言这些&#xff0c;就以现实举例&#xff0c;我…

每日练习之排序——链表的合并;完全背包—— 兑换零钱

链表的合并 题目描述 运行代码 #include<iostream> #include<algorithm> using namespace std; int main() { int a[31];for(int i 1;i < 30;i)cin>>a[i];sort(a 1,a 1 30);for(int i 1;i < 30;i)cout<<a[i]<<" ";cout&…

Mysql之Innodb存储引擎

1.Innodb数据存储 innodb如今能够做到mysql的默认数据存储引擎&#xff0c;肯定有着其好处的&#xff0c;那么innodb有什么好处呢? 1. 当意外断电或者重启&#xff0c; InnoDB 能够做到奔溃恢复&#xff0c;撤销没有提交的数据 2.InnoDB 存储引擎维护自己的缓冲池&#xff0c…

医院挂号就诊系统的设计与实现

前端使用Vue.js 后端使用SpiringBoot MyBatis 数据使用MySQL 需要项目和论文加企鹅&#xff1a;2583550535 医院挂号就诊系统的设计与实现_哔哩哔哩_bilibili 随着社会的发展&#xff0c;医疗资源分布不均&#xff0c;患者就诊难、排队时间长等问题日益突出&#xff0c;传统的…

Hadoop3:HDFS的Fsimage和Edits文件介绍

一、概念 Fsimage文件&#xff1a;HDFS文件系统元数据的一个永久性的检查点&#xff0c;其中包含HDFS文件系统的所有目 录和文件inode的序列化信息。 Edits文件&#xff1a;存放HDFS文件系统的所有更新操作的路径&#xff0c;文件系统客户端执行的所有写操作首先 会被记录到Ed…

二叉树的链式结构

1.二叉树的遍历 2.二叉树链式结构的实现 3.解决单值二叉树题 1.二叉树的遍历 1.1前序&#xff0c;中序以及后序遍历 二叉树的遍历是按照某种特定的规则&#xff0c;依次对二叉树的结点进行相应的操作&#xff0c;并且每个结点只操作一次。 二叉树的遍历有这些规则&#xff…

主流电商平台商品实时数据采集API接口||抖音电商数据分析实例|可视化

— 1 — 抖音电商数据【抖音电商API数据采集】分析场景 1. 这里&#xff0c;我们选择“伊利”这个品牌作为案例进行分析&#xff0c;在短短的4个月里&#xff0c;从最初每月营收17.07万&#xff0c;到6月份达到了2485.54 万&#xff0c;伊利的牛奶&#xff0c;有点牛&#xff…