C++练级计划-> 《IO流》iostream fstream sstream详解

news/2024/11/29 18:20:03/

如果是想全部过一遍就看完,如果想具体的了解某一个请点目录。因为有三种流的使用可能内容多 

目录

流是什么?

C++IO流(iostream)

io流的注意事项

cin和cout为什么能直接识别出类型和数据

fstream

fstream的使用方法: 

1.以二进制打开文件并写入和读取

2.以文本打开文件并读取或写入

3.用>> << 重载符号读取或写入

sstream

stringstream:

1.提取stringstream流中的数据

2.删除stringstream流中的数据

3.stringstream的常见用法:

4.stringstream能使用的oj题:


流是什么?

首先io流就是iostream,全称 in out stream,输入输出流。

怎么理解流呢?

把它想成一个数据结构(抽象的),里面流动的(存的)是字节流,或者字符流。

字节流就是二进制数据,字符流就是字符数据。二进制数据主要是图片视频等,字符数据就是一个文档全是字的。

 所以流就可以想象成从一个地方拿数据,然后供给另一个地方,南水北调,南边的水,供给北方

这里中间传输的过程就是流。南水放入,北方取出加工使用。

C++IO流

这里的ios_base就是大基类(父类),里面保存的就是每个流都应该有的功能,ios是继承自ios_base的一个类,但是不只是只有一个ios,这里的ios类旨在处理char单字符,而对于wchar这样的宽字符它是无法处理的,所以还有另外一个wios类专门用于处理wchar。

ios就是后面的所有类的基类(父类)

iostream(经常用于屏幕打印数据)

in out stream

cin:流提取(istream),用于从io流中提取数据,比如说读文件、获取键盘的信息等

cout:流插入(ostream),将数据放入io流中,供其他程序提取。比如写文件(将数据写到屏幕上就是打印)

cerr:也是流插入(ostream)。某处出错时,将错误数据放入io流。一般在屏幕打印

clog:也是流插入(ostream)。进行日志的输出,屏幕打印

fstream(文件)

file stream:顾名思义这个流是给文件使用的。

sstream(字符串)

string stream:这个则是给字符串使用的。

io流的注意事项

注意:1.cin是以空格和换行为分隔符的

在使用cin时如果我们在输入时,数据中间加了空格,有人要提取数据,提取到的是空格前的数据。下一次有人又来提取时,这时是先把之前空格后的数据先给出去。

#include <iostream>
using namespace std;
int main()
{int a = 0, b = 0;cin >> a; //输入:10 20cout << a << endl;cin >> b; //直接从输入缓冲区提取cout << b << endl;return 0;
}

如上代码我们输入时输入 10 20,第二次cin时根本不会停下来等你输入数据,而是直接把20给b。然后输出。所以在使用cin时要注意空格的使用

2.输入类型和要输出到的类型必须一致

3.getline函数:用于输入时只把换行当做分隔符。

这个函数只能用于字符串,所以1.中输入数字的情况用不了

#include <iostream>
#include <string>
using namespace std;
int main()
{string s;//cin>>s;          //cin输入,最终只输出hellogetline(cin, s);   //输入:"hello world"cout << s << endl; //输出:"hello world"return 0;
}

cin和cout为什么能直接识别出类型和数据

cin重载的>>运算符

 cout重载的<<运算符

在C++标准库中对于内置类型的输入和输出已经全部重载,所以cin和cout能识别类型是这个原因。对于自定义类型而言: class类,在定义类时如果需要使用>> 和 << 需要自己手写接口实现。实现方法对应自己类的功能。

fstream

fstream有三个类和一个filebuf缓冲区

文件流的三个类:

对应操作场景
ofstream只写
ifstream只读
fstream读+写

 文件的打开方式:

打开方式功能
in以读的方式打开文件
out以写的方式打开文件
binary以二进制方式对文件进行操作
ate输出位置从文件的末尾开始
app以追加的方式对文件进行写入
trunc先将文件内容清空再打开文件

文件流的函数:

成员函数功能
put插入一个字符到文件
write插入一段字符到文件
get从文件提取字符
read从文件提取多个字符
tellg获取当前字符在文件当中的位置
seekg设置对文件进行操作的位置
>>运算符重载将数据形象地以“流”的形式进行输入
<<运算符重载将数据形象地以“流”的形式进行输出

fstream的使用方法: 

1.以二进制打开文件并写入和读取

写入文件:

#include <iostream>
#include<fstream>
using namespace std;
void ofsteam_test_binary()
{//为什么o是写入,output是输出的意思,意味着我们要从流中输出给文件ofstream ofs;ofs.open("binoptest.txt", ofstream::binary | ofstream::out);//以二进制写的方式打开文件char str[] = "中国无敌";ofs.write(str, strlen(str));ofs.put('!');//put是单字符的写入//使用任何类时都要记得closeofs.close();
}
int main()
{ofsteam_test_binary();return 0;
}

解释:我们创建一个ofstream对象,用二进制out的方式打开文件binoptest.txt,为什么out是输出这里我们要把视角看成是流的视角:流把数据output进了binoptest.txt,所以ofstream是输出流。

结果:

1.在当前目录生成一个binoptest.txt文件 

2.文件内容为:

读取文件:

void ifstream_test_binary()
{ifstream ifs;ifs.open("binoptest.txt", std::ios::binary | std::ios::in);char str[32];//计算文档内容的大小ifs.seekg(0,std::ios::end);int len = ifs.tellg();ifs.seekg(0,std::ios::beg);//读取文件放入strifs.read(str, len);ifs.close();//字符串末尾置为0str[len] = '\0';printf("%s", str);
}

解释:创建ifstream对象,打开文件创建str储存读取出来的数据。

注意:计算文档大小没有什么size函数但是可以用下面的代码

//计算文档内容的大小ifs.seekg(0,std::ios::end);int len = ifs.tellg();ifs.seekg(0,std::ios::beg);

seekg用来定位读指针,第一个参数是偏移量,代表从哪里开始定位,第二个参数是根据偏移量后从哪里开始end代表结尾,beg代表开始,我们一开始就把定位移到了最后,然后tellg是用来计算当前读指针的偏移量的(从头开始计算),然后再让读指针回到beg开始,就完成了一次文档计数

结果 :

2.以文本打开文件并读取或写入

写入文件:

void ofstream_test_text()
{ofstream ofs;//默认的output方式是文本的ofs.open("text.txt");char str[] = "中国无敌";ofs.write(str, strlen(str));ofs.put('!');//put是单字符的写入//使用任何类时都要记得closeofs.close();
}

 和二进制的区别只是,在open时二进制文件和文本文件不同,open默认打开文件是以文本方式打开的,如果要使用二进制打开就需要设置打开方式。

结果:

读取文件:

void ifstream_test_text()
{ifstream ifs;ifs.open("text.txt");char str[32];//计算文档内容的大小ifs.seekg(0, std::ios::end);int len = ifs.tellg();ifs.seekg(0, std::ios::beg);//读取文件放入strifs.read(str, len);ifs.close();//字符串末尾置为0str[len] = '\0';printf("%s", str);
}

和写入文件一样:和二进制的区别就是open的打开方式。

结果: 

注意:除了指定二进制外,我们还可以指定读和写:默认的情况下:ifstream打开文件是以读的方式,ofstream打开文件是以写的方式打开,而fstream是以读加写的方式打开。

3.用>> << 重载符号读取或写入

写入文件:

void writefile()
{ofstream ofs;ofs.open("file.text");string s = "中国无敌!";ofs << s;
}

结果:

读取文件:

void readfile()
{ifstream ifs;ifs.open("file.text");string s;ifs >> s;cout << s;ifs.close();
}

结果:

 

可以看出如果以重载符来写入或者读取时使用方法和cout 和 cin 类似区别只是在于 cout 和 cin的默认设备分别是屏幕和键盘,而我们用文件流的写入和读取,可以自己选择文件。键盘和屏幕也是文件。 

sstream

对应操作场景
ostringstream输出操作
istringstream输入操作
stringstream输入操作+输出操作

介绍一下:sstream 全称 stringstream 字符串流:顾名思义一定和字符串有关,而这里的stringstream就是用来解决字符串转换的问题,在c语言时要进行字符串转换就要用到itoa等函数,在c++中用stringstream就可以完成 

stringstream:

因为用法类似所以这里只介绍stringstream,stringstream是在底层维护了一个字符串,在这个字符串中完成对应的操作,放进这个字符串的数据默认就变成字符了。

1.提取stringstream流中的数据

有两种从流中提取数据的方法:

    s.str(""); //将stringstream底层管理的string对象设置为""。s.clear(); //将上次转换状态清空掉

1.使用>>从流中提取

    int a = 10;string sa;stringstream s;s << a; //将int类型的a放入输入流s >> sa; //从s中抽取前面插入的int类型的值,赋值给string类型(方式一)cout << sa << endl;

2.使用.str()函数的方式提取

    double b = 3.14;s << b;sa = s.str(); //获取stringstream中管理的string类型(方式二)cout << sa << endl;

二者没什么差别>>是将stringstream中的内容通过复制的方式给出,而 .str()是通过 返回一个字符串的方式然后在赋值给出。

2.删除stringstream流中的数据
    s.str(""); //将stringstream底层管理的string对象设置为""。s.clear(); //将上次转换状态清空掉

上面的代码,首先将stringstream中的字符串给变为空字符串,然后用clear函数将状态清空。关于这个状态又是一个知识点:

stringstream底层在一次转换完成后会把标志位记成badbit这时代表的是流不可转换数据,使用clear后变成goodbit流才可转换。但是clear只是更改标记位而不会对内置的字符串进行更改所以这时需要将str置为空。

3.stringstream的常见用法:

1.将数据转换为字符类型

    int a = 10;string sa;stringstream s;s << a; //将int类型的a放入输入流s >> sa; //从s中抽取前面插入的int类型的值,赋值给string类型(方式一)cout << sa << endl;

2.字符串的拼接

#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{string rets;stringstream s;s << "2021" << "dragon"; //将多个字符串放入stringstream中s >> rets; //方式一获取cout << rets << endl;s.str(""); //将stringstream底层管理的string对象设置为空字符串s.clear(); //将上次转换状态清空掉s << "Thanks" << " " << "for" << " " << "reading"; //将多个字符串放入stringstream中rets = s.str(); //方式二获取cout << rets << endl;return 0;
}
4.stringstream能使用的面试题:

1.统计字符串的个数

输入:“hello world c plus plus”
输出:5

#include <iostream>
#include <sstream>
#include <string>using namespace std;int main() {string str = "hello world c plus plus";int count = 0;stringstream ss(str);string word;while (ss >> word)count++;cout << count << endl;return 0;
}

很简单因为使用 >> 符号是以空格或者换行为分割符的,所以只要统计总共有几次输入进流中即可。 

2.反转字符串中的单词

class Solution {
public:string reverseWords(string s) {string res,temp;stringstream ss(s);while(ss>>temp){cout<<temp<<endl;res = temp + " " + res;}if(!res.empty()){res.pop_back();}return res;}
};

这题也很简单,将s 传入 ss的构造函数中,这时ss的底层里保存的就是s。此时通过>>流提取符号放入temp中,将数据类似头插的方法将temp放到res前面最后再把最后的空格删除。从这里也可以看出stringstream的>> 流插入符号是从字符串头的位置开始插入的,所以才能让temp中每次只出现一个字符串。


http://www.ppmy.cn/news/1550958.html

相关文章

<<WTF-Solidity>>学习笔记(part 5-8)

part 5 : 数据位置 Solidity数据存储位置有三类&#xff1a;storage&#xff0c;memory和calldata。不同存储位置的gas成本不同。storage类型的数据存在链上&#xff0c;类似计算机的硬盘&#xff0c;消耗gas多&#xff1b;memory和calldata类型的临时存在内存里&#xff0c;消…

SQL:多字段混合去重后编号

SQL SERVER 库表存储人员记录&#xff0c;来自多种源数据&#xff0c;如果两条记录的 Name、Phone、Email 字段之一有重复&#xff0c;则说明这两条记录是同一个人。null 是数据未知&#xff0c;两条记录的字段都为 null 时表示两者默认不重复&#xff0c;是否重复要靠其他字段…

React Router v7正式发布:开启全栈框架新时代

概述 2024年11月22日&#xff0c;React Router团队宣布React Router v7正式发布。这一重大版本不仅将Remix的大量特性整合到了React Router中&#xff0c;还为React Router用户开启了全新的“框架模式”&#xff0c;使得开发者可以直接使用Remix的功能。这标志着React Router从…

设计有一个 “分布式软总线“ 系统,跨平台

设计一个 跨平台的分布式软总线 系统是为了实现不同设备间的通信&#xff0c;支持各种硬件平台和操作系统&#xff0c;且能够通过统一的协议进行互联互通。这样的系统通常用于物联网&#xff08;IoT&#xff09;场景、智能家居、智能制造、车联网等应用。以下是一个详细的设计方…

Spring Cloud Stream实现数据流处理

1.什么是Spring Cloud Stream&#xff1f; Spring Cloud Stream的核心是Stream&#xff0c;准确来讲Spring Cloud Stream提供了一整套数据流走向&#xff08;流向&#xff09;的API&#xff0c; 它的最终目的是使我们不关心数据的流入和写出&#xff0c;而只关心对数据的业务处…

Linux快速入门:3.硬盘分区与RHEL8系统安装

点击蓝字 | 关注我们 规划Linux的硬盘分区 在安装RHEL8前&#xff0c;我们先根据上节的内容Linux快速入门&#xff1a;2.Linux的文件系统和目录结构&#xff0c;对硬盘进行分区规划。 对于Linux初学者&#xff0c;在学习过程中建议分区方案越简单越好&#xff0c;只需要将硬盘分…

Vim操作指南

Vim 是一款功能强大的文本编辑器&#xff0c;它广泛应用于程序员、系统管理员和普通用户的日常工作中。Vim 以其高效、灵活和可扩展性著称&#xff0c;虽然上手有一定难度&#xff0c;但掌握后可以极大提高编辑效率。本指南旨在为用户提供一个详细的 Vim 操作教程&#xff0c;从…

人工智能技术的工程伦理问题 --以美团外卖大数据杀熟为例

引言 最近朋友圈刷屏的一篇文章《我被美团会员割了韭菜》很多人都看过&#xff0c;针对该事件&#xff0c;网经社电子商务研究中心主任曹磊指出&#xff1a;大数据“杀熟”暴露出大数据产业发展过程中的非对称以及不透明。由此也带来的最大伦理危机—个人隐私权问题。 背景信…