当前位置:首页 » 《随便一记》 » 正文

【C++】第九章:IO流__zhy_cq

21 人参与  2021年12月24日 17:06  分类 : 《随便一记》  评论

点击全文阅读


【C++】第九章:IO流

文章目录

  • 【C++】第九章:IO流
  • 一、C语言的输入输出
  • 二、流的概念
  • 三、C++的IO流
    • 1.C++标准IO流
    • 2.C++文件IO流
      • ①.定义文件流对象
      • ②.打开文件
      • ③.对文件进行读写操作
      • ④.关闭文件
    • 3.operator<< 和 operator>>写入和读取
  • 四、stringstream流

一、C语言的输入输出

在C语言中用到的输入输出方式就是scanf ()与printf()。

  • scanf(): 从标准输入设备(键盘)读取数 据,并将值存放在变量中。

  • printf(): 将指定的文字/字符串输出到标准输出设备(屏幕)。

    C语言借助了相应的缓冲区来进行输入与输出。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kW9j9yAW-1632126228688)(D:\github\gitee\bolgs\【C++】第九章:IO流.assets\1632106433155.png)]

这些缓冲区(流)会有一些缓冲机制,如行缓冲,但流中遇到\n号时,就会自动刷新到相关的文件中。

解释一下输入输出缓冲区的理解:

1.可以屏蔽掉低级I/O的实现,也就是IO系统调用。 如read,open,write。它们这些系统调用函数,是直接与文件打交到的,没有缓冲,没有流的概念。

2.可以使用这部分的内容实现“行”读取的行为,通过解析缓冲区的内容,返回一个“行”。

二、流的概念

C++流是指信息从外部输入设备(如键盘)向计算机内部(如内存) 输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。

先要明确的是,在标准IO里面,这些函数都是对流的操作,那么什么是流呢?可以把流直观地理解为一段缓冲区,如stdin便准输入流,可以把它理解为一段缓冲区,每个流都与一个文件相关连了,stdin流也不例外,它默认与屏幕这个文件(UNIX中一切皆文件的思想)相连。

三、C++的IO流

在C++的IO中有很庞大的类库支持,通过继承关系衍生出了很多不同的输入输出的类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OrMfHTEW-1632126228689)(D:\github\gitee\bolgs\【C++】第九章:IO流.assets\1632106736182.png)]

1.C++标准IO流

C++标准库提供了4个全局流对象cincoutcerrclog

  • 使用cout进行标准输出,即数据从内存流向控制 台(显示器)。

  • 使用cin进行标准输入即数据通过键盘输入到程序中。

  • cerr用来进行标 准错误的输出。

  • clog进行日志的输出。

    从上图可以看出,coutcerrclogostream类的三个不同的 对象。

    举个例子:

std::cout << "hello world";
std::cerr << "hello world";
std::clog << "hello world";

注意C++的标准IO都是以空格或者\n(回车换行)为结束符的,也就是缓冲区中内容由这两个符号隔开,遇到空格或者回车的时候,就将缓冲区中的内容刷新到屏幕上。因此就形成了“行”的概念。

#include <iostream>
#include <string>
using namespace std;

int main() 
{
	string str;
    cin >> str; // 输入hello world
    cout << str; // 输出 hello
    cin >> str; // 不会等待输入,而是将在空格后面的world直接放入
    cout << str; // 输出world
    // 最后看到的效果就是输入hello world,然后直接输出helloworld(其中的空格被缓冲区获取了)
    return 0;
}

如果想要获取一行的信息的时候,可以使用getline()函数。因为getline()函数只会以\n,也就是回车为结束符,遇到空格还是会继续的。

getline(cin, str);// 从cin中获取数据到str中,假设输入hello world
cout << str; // 输出hello world

补充:在多组数据要输入的时候。

1.一般C语言就是使用scanf(),知道遇到文件结束符EOF也可以使用ctrl + c

while (scanf("%d", &x) != EOF)

2.在C++中可以直接使用cin

while (cin >> x)

当没有数据的时候,cin对象会返回一个bool值。即operator bool() const函数将对象转化为bool然后返回false使得while结束。

2.C++文件IO流

C++根据文件内容的数据格式分为二进制文件和文本文件。采用文件流对象操作文件的一般步骤:

①.定义文件流对象

定义的时候,需要包含头文件#include <fstream>

文件流作用
ofstream创建文件并向文件中写入信息
ifstream从文件中读取信息
fstream可以创建文件并写入也可以读取文件中的信息
#include <fstream>
using namespace std;

int main()
{
    ofstream outFile; // 可写入
    ifstream inFile; // 可读取
	fstream File; // 可写可读
    return 0;
}

②.打开文件

在从文件读取信息或者向文件写入信息之前,必须先打开文件。

打开的方式:使用open()函数进行文件打开。如下:

ofstream outFile;
outFile.open("test.txt"); // ofstream默认以写的方式打开文件
   
ifstream inFile;
inFile.open("test.txt"); // ifstream默认以读的方式打开文件

fstream file;
file.open("test.txt"); // fstream默认以读+写的方式打开文件

文件打开的方式:

除了默认的打开方式还有很多的文件打开方式:

模式描述
ios::in以读的方式打开
ios::out以写的方式打开
ios::trunc如果此文件已经存在, 就会打开文件之前把文件长度截断为0
ios::app尾部追加方式打开
ios::ate文件打开后,定位到文件末尾
ios::binary以二进制方式打开

举例:如果想要进行写的操作,又想从尾部开始写,就可以使用位操作符|组合起来:

ofstream outFile;
outFile.open("test.txt", ios::out | ios::app)

③.对文件进行读写操作

成员函数功能描述
put插入一个字符到文件中
wirte插入一段字符串到文件中
get从文件中提取字符
read从文件中提取多个字符
tellg获取当前字符在文件当中的位置
seekg设置对文件进行操作的位置(三个位置beg cur end
operator<<数据输出
operator>>数据输入

举例:想要打开一个文本文件,在写入数据之后,再打开这个文件,读取数据。

void Write()
{
    ofstream outFile;
    outFile.open("test.txt", ios::out); // 以写的方式打开文件
    char str[] = "hello zhy"; 
    outFile.write(str, strlen(str)); // 将str写入文件当中
    outFile.put('~'); // 将~写入文件
    outFile.close();
}

void Read()
{
    ifstream inFile;
    inFile.open("test.txt", ios::in); // 以读的方式打开文件
    inFile.seekg(0, inFile.end); // 定位到文件的末尾
    int len = inFile.tellg();  // 定位当前的位置,因为当前在文件的末尾,所以len就是文本的长度
    inFile.seekg(0, inFile.beg); // 定位会文件的开头
    char str[20];
    inFile.read(str, len); // 读取len个字符到str中
    inFile.close();
}

④.关闭文件

使用close()函数对文件对象进行关闭。

fstream file;
file.open("test.txt");
file.close();  // 关闭文件

3.operator<< 和 operator>>写入和读取

在C++中可以直接使用流这样的概念和operator<<operator>>这样的函数,就可以完成以上四部操作。

举例:

void Write()
{
    ofstream outFile("test.txt");
    outFile << "hello zhy~";
}

void Read()
{
    ifstream inFile("test.txt");
    char str[20];
    inFile >> str;
}

总结:显然使用流对象的方式更加的形象,也更加简洁。

四、stringstream流

在C语言中我们需要使用向sscanf(),sprintf()这样的函数将整形的数据转化成为字符串类型的格式。在C++中同样提供了流对象这样我的概念去简化转化的操作。

<sstream>的头文件下,有这样三个类可以帮助我们:

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

一般我们都使用stringstream对整形变量或字符串进行操作。

#include <iostream>
#include <sstream>
using namespace std;

int main()
{
    int num = 100;
    stringstream ssin;
    ssin << num; // 将100输入给ssin当中
    string str;
  	ssin >> str; // 将ssin中的内容赋值给str
    return 0;
}

stringstream对象可以使用str()函数,将stringstream对象中的内容以字符串的形式返回;或者可以使用str()函数对stringstream对象中的内容进行覆盖。

#include <iostream>
#include <sstream>
using namespace std;

int main()
{
    int num = 100;
    stringstream ssin;
    ssin << num; // 将100输入给ssin当中
    cout << ssin.str(); // 以字符串的形式输出100
    ssin.str("hello"); // 将hello覆盖在ssin中
    cout << ssin.str(); // 输出hello
    return 0;
}

使用的注意事项:

1.stringstream实际是在底层维护了一个string类型的对象用来保存结果。

2.stringstream在转换结尾时(即最后一个转换后),会将其内部状态设置为badbit,因此在下一次转换前必须调用clear将状态重置为goodbit才可以转换,但clear不会将stringstream底层的string对象清空,而是清空对象的状态。

3.可以使用s.str("")的方式将stringstream底层的string对象设置为空字符串,否则多次转换时,会将结果全部累积在底层string对象中。

4.获取stringstream转换后的结果有两个方法,一是使用>>之间从流当中提取,二是使用s.str( )获取stringstream底层的string对象。

5.stringstream使用string类对象代替字符数组,可以避免缓冲区溢出的危险,而且其会对参数类型进行推演,不需要格式化控制,也不会存在格式化失败的风险,因此使用更方便,更安全。


点击全文阅读


本文链接:http://zhangshiyu.com/post/32090.html

文件  打开  对象  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1