C/C++语言基础--C++IO流、输入输出流、文件流、字符串流、重定向流等详解

news2024/10/3 4:11:33

本专栏目的

  • 更新C/C++的基础语法,包括C++的一些新特性

前言

  • 流思想,我认为在计算机中是一个很重要的思想,因为计算机、编程无非就是获取数据,然后对数据进行操作;
  • C++给主要给我们提供了3种流,输入输出流、文件流、字符串流,这篇就是小编的学习笔记,希望大家能够批评指正。

文章目录

    • IO流
    • 标准输入输出流
      • 类和流对象
      • 标准输入流
        • >>读取
        • cin.get()
        • cin.getine()
        • cin.ignore
      • 标准输出流
    • 文件流
      • 简介
      • 使用
        • 打开文件
        • 读取文件
          • 使用>>读取
          • 使用read()读取
          • 使用std::getline读取
        • 写入文件
          • 使用<<写入
          • 使用write写入
      • 打开模式
      • 文件位置指针
      • 文件操作的一些函数
    • 字符串流
      • 打开字符串流
      • 从string反格式化
    • 重定向流
      • 代码实重定向
        • C语言方式
        • C++方式

IO流

咱已经学过了 C 语言,所以都知道,C语言有有一整套完成数据读写(I/O)的解决方案:

  • 使用 scanf()、gets() 等函数从键盘读取数据,使用 printf()、puts() 等函数向屏幕上输出数据;
  • 使用 fscanf()、fgets() 等函数读取文件中的数据,使用 fprintf()、fputs() 等函数向文件中写入数据。
  • 使用sscanf() 读取格式化的字符串中的数据,使用sprintf()把格式化的数据写入到字符串

要知道,C 语言的这套 I/O 解决方案也适用于 C++ 程序,但 C++ 自己独立开发了一套全新的 I/O 解决方案,其中就包含大家一直使用的 cin 和 cout,但是要注意,cin、cout是类,printf、scanf是函数调用。

C++标准流,提供了一下三个方面的内容:

  1. 系统指定的标准设备的输入和输出。即从键盘输入数据,输出到显示器屏幕,简称标准I/O。
  2. 外存磁盘文件为对象进行输入和输出,简称文件I/O。
  3. 内存中指定的空间进行输入和输出,,简称串I/O。

流的概念:数据传输,输入、输出像水一样,故将这个过程定义为流。

标准输入输出流

类和流对象

重点关注前两个即可。

流类预定义流对象描述
istreamcin(常用)标准输入流
ostreamcout(常用)标准输出流
ostreamcerr标准错误流(不缓冲数据,直接显示)
ostreamclog标准日志流(缓冲数据)

标准库定义了 4 个 IO 对象。

  • 处理输入时使用命名为cin的 istream 类型对象,称为标准输入。

  • 处理输出时使用命名为cout的 ostream 类型对象,称为标准输出。

  • 标准库还定义了另外两个 ostream 对象,分别命名为 cerr 和 clog,cerr 对象又叫作标准错误,通常用来输出警告和错误信息给程序的使用者。

  • 而 clog 对象用于产生程序执行的一般信息。

标准输入流

cin本身是会略过所有空格、回车、tab的,然后开始读入,遇到空格、回车、tabl停止读入,光标会停留在这些字符之前,意思就是下一次读入也会从空格后开始读取。

>>读取

C++给我们提供了方便的输入方法,直接使用>>即可,但是遇到空格会被截断

cin.get()

读取一个字符,也可以连续读取

char c;
char buf[20],buf1[20];
//读取一个字符
c = cin.get();	//<==> cin.get(c);
//读取字符串
cin.get(buf, 20);
//读取字符串,遇到指定的字符终止读取
cin.get(buf1, 20, '#');
cout << c << " " << buf<<" "<< buf1;
cin.getine()

读取一行

char buf[20];
cin.getline(buf, 20);
cin.getline(buf, 20, '#');
cin.ignore

忽略

std::string str;
//忽略所有\n
while (cin.peek() == '\n')
{
	cin.ignore(1);
}	
std::getline(cin, str,'#');
// 输出
cout << str << endl;
/*
输入:
\n
\n
123#
输出:
123
*/

标准输出流

C++格式化输出3种使用方式:

  1. 通过流成员函数进行输入输出格式控制
// 设置输出内容宽度
cout.width(30);
// 设置填充内容
cout.fill('*');
// 设置对其方式
cout.setf(ios::left);
// 用科学计数法展示
cout.setf(ios::scientific);

// 八进制格式输出
cout << oct << 0xA << endl;
// 十进制格式输出
cout << dec << OxA << endl;
// 大写形势展示十六进制中字母
cout.self(ios::uppercase);
// 十六进制格式显示
cout << hex << OxA << endl;

// 取消科学计数法使用
cout.unself(ios::scientific);
// 设置浮点数显示前N位
cout.precision(3);
cout << 3.1415 << endl;  // 输出 3.142,最后一位四舍五入

// ………………………… 还有很多,现用现查即可。

这里有些设置会全局生效,所以有还需要关闭,时候很不方便。

  1. 通过#include 提供的控制符,进行输入输出格式控制,如下:
控制符作用
setbase(n)设置整数为n进制
setfill(n)设置字符填充
setprecision(n)设置浮点数有效位
setw()设置字段宽度
setiosflags(ios::fixed)设置浮点数固定小数位输出
setiosflags(ios::scientific)浮点数以科学计数法表示
setiosflags(ios::left)左对齐
setiosflags(ios::right)右对齐

当然还有很多,先用现查即可。

案例

cout << setw(30) << setfill('*') << setiosflags(ios::left) << 1.2222233 << endl;

// 输出: 1.22222***********************

而且这个具有临时性,不会影响后面输出。

  1. 运用C语言的API

可以用C语言的scanf进行格式化输出。

文件流

简介

文件:字节流,即如何从文件读取流和向文件写入流。

C++ 给操作文件提供了一个标准库 fstream,它定义了三个新的数据类型:

在这里插入图片描述
在这里插入图片描述

使用

其实任何语言文件操作都差不多,打开、关闭、读取与写入(字节、一行、二进制等)

打开文件
fstream file("maye.txt");

可以通过构造函数指定文件名,并打开;默认就是以可读可写的方式打开的,但是文件不存在会打开失败!

file.open("maye.txt", ios::in | ios::out | ios::trunc);

也可以使用open函数打开文件,使用open必须传递打开模式ios::in为可读,ios::out为可写,ios::trunc为文件不存在时创建,存在则清空所有内容(ios::trunc必须与ios::out搭配使用)。

if (!file)	//if (!file.is_open())	//两种判断方式都可以
{
	cout << "open error:" << strerror(file.rdstate());
}
else
{
	cout << "open successed";
}

file.close();

注意: 使用完毕之后并不需要手动关闭文件,但是如果想提前关闭可以使用close()函数。

读取文件

文件打开之后,就可以进行读写了,注意打开模式,ios::in为可读,ios::out为可写。

创建stu.txt文件,并写入以下内容,并测试读取!

123 wy 男
456 lt 男
789 wgs 男
110 lyp 男

如果乱码,则将文件存为ansi(win11中记事本)

使用>>读取
std::string buf;
while (!file.eof())  // 判断是否读到了文件最后
{
	file >> buf;		//读成功返回true
	cout << buf << " ";
	if (file.peek() == '\n')
	{
		cout << endl;
	}
}

注意,使用>>读取,遇到空格会截断,所以需要循环的去读取,而且还需要自己判断是不是\n。

使用read()读取
char buf[200] ={0};
file.read(buf, 200);
cout << buf;

注意:我们并不知道文件有多大,所以并不能很好的指定读取的大小,从而一次性把文件读取完成。可以先获取文件大小然后再读取

file.seekp(0,ios::end);
int64_t len = file.tellp();   // 获取文件大小
file.seekp(0,ios::beg);

char* buf = new char[len + 1] {0};       //及其重要
file.read(buf, len);
cout << buf;

delete[] buf;
使用std::getline读取

如果想直接读取到std::string里面,则需要使用std::getline。

std::string buf;
std::getline(file, buf);
cout << buf;

这样读取只能读取一行,如果想要读取多行,则需要使用循环。

std::string buf;
while (!file.eof())
{
	std::getline(file, buf);
	cout << buf << endl;
}
写入文件
  • 如果想要追加写入文件,请添加打开模式ios::app

  • 如果想要二进制读写,请添加打开模式ios::binary

使用<<写入
使用write写入

打开模式

模式标记适用对象作用
ios::inifstream fstream打开文件用于读取数据。如果文件不存在,则打开出错。
ios::outofstream fstream打开文件用于写入数据。如果文件不存在,则新建该文件;如果文件原来就存在,则打开时清除原来的内容。
ios::appofstream fstream打开文件,用于在其尾部添加数据。如果文件不存在,则新建该文件。
ios::ateifstream打开一个已有的文件,并将文件读指针指向文件末尾(读写指 的概念后面解释)。如果文件不存在,则打开出错。
ios:: truncofstream打开文件时会清空内部存储的所有数据,单独使用时与 ios::out 相同。
ios::binaryifstream ofstream fstream以二进制方式打开文件。若不指定此模式,则以文本模式打开。
ios::in | ios::outfstream打开已存在的文件,既可读取其内容,也可向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。
ios::in | ios::outofstream打开已存在的文件,可以向其写入数据。文件刚打开时,原有内容保持不变。如果文件不存在,则打开出错。
ios::in | ios::out | ios::truncfstream打开文件,既可读取其内容,也可向其写入数据。如果文件本来就存在,则打开时清除原来的内容;如果文件不存在,则新建该文件。

文件位置指针

istream 和 ostream 都提供了用于重新定位文件位置指针的成员函数。这些成员函数包括关于 istream 的 seekg(“seek get”)和关于 ostream 的 seekp(“seek put”)。

seekg 和 seekp 的参数通常是一个长整型。第二个参数可以用于指定查找方向。
查找方向:

  • ios::beg 默认的,从流的开头开始定位
  • ios::cur 从流的当前位置开始定位
  • ios::end 从流的末尾开始定位

案例

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

struct Gril {
    int age;
    string name;
};

int main()
{
    Girl mygirl[3] = {18, "w", 19, "y", 10, "l"};
    
    // 打开文件
    fstream file("./test.txt", ios::in | ios::out | ios::binary | ios::trunc);
    if(!file) {
        cerr << "file open failed" << endl;
    }
    
    // 写入文件
    file.write((char*)mygirl, sizeof(mygirl));
    
    // 文件指针移动到开头
    file.seekg(ios::beg);  
    
    //读
    Girl temp[3];
    file.read((char*)temp, sizeof(temp));
        
    for(auto& it : temp) {
        cout << it.age << " " << it.name << endl;
    }
    
    file.close();
    
    return 0;
}

文件操作的一些函数

这张图是当时我学《C++ prime》这本书的时候在博客找的,我感觉还是很清晰的讲解了文件操作相关的函数

在这里插入图片描述

字符串流

在C语言中,我们使用sscanf和sprintf来对字符串进行格式化,格式控制非常不方便,在C++中有了更方便的操作。

使用头文件添加对字符串流的支持。

我感觉,这个最大的作用就是,格式化与反格式化

打开字符串流

stringstream stream(ios::out | ios::in);

如果支持格式化和反格式化,则需要指定打开模式ios:inios::out

stream << 1 <<" " << "234"s <<" "<< 5.20;

使用stream对象,把需要的数据全部格式化,这里每个数据之间用空格隔开,方便等会反格式化。(反格式化以空格为分割字符)

cout << stream.str()<<endl;

当然在反格式化之前,我们使用stream.str()查看已经格式化的数据

int a;
float b;
string s;

首先我们定义三个对象,来接受从stream中反格式化的数据。

stream >> a >> s >> b;
cout << a <<" " << s << " " << b << endl;  // 反格式化的意思就是,输出的时候按照不同的数据类型自动识别,不受输入影响

从string反格式化

stringstream对象还可以绑定一个string对象,直接对string进行操作。

string buf = "1 234 5.20";
stringstream stream(buf);

先准备一个string对象,然后构造stringstream,默认以可读可写方式打开。

int a;
float b;
string s;
stream >> a >> s >> b;
cout << a << " " << s << " " << b << endl;   // 反格式化

如果在反格式化之后需要写入内容,是写入不了的,需要调用stream.clear()对格式进行清除,代码如下:

// 清除操作
stream.clear();
stream << "@@" << " ##";
cout << stream.str();

如果这个时候像着追加继续写,则只需要在构造stringstream对象的时候,添加上ios::app以追加的模式写入即可,如下:

stringstream stream(buf,ios::app | ios::in | ios::out);   

重定向流

重定向流:我们一般输入输出一般都是在屏幕、键盘上操作,键盘输入,屏幕输出,重定向流就是可以指定输出位置,比如说输出到文件,不输出到屏幕

代码实重定向

C语言方式

C语言方式可以通过freopen函数实现:

freopen("in.txt","r",stdin);	//stdin重定向到in.txt
//...
freopen("CON","r",stdin);		//恢复重定向

freopen("out.txt","w",stdout);

freopen("CON","w",stdout);
C++方式

C语言方式可以通过cin.rdbuf函数实现:

fstream fin("in.txt");
streambuf* oldbuf = cin.rdbuf();
cin.rdbuf(fin.rdbuf());
//...
cin.rdbuf(oldbuf);

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

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

相关文章

react-问卷星项目(4)

项目实战 使用CSS 尽量不要使用内联CSS 内联style代码多&#xff0c;性能差&#xff0c;扩展性差外链css文件可复用代码&#xff0c;可单独缓存文件 元素内联style 和HTMl元素的style相似必须用JS写法&#xff0c;不能是字符串&#xff0c;里面必须是对象 <span style…

# VirtualBox中安装的CentOS 6.5网络设置为NAT模式时,怎么使用SecureCRT连接CentOS6.5系统?

VirtualBox中安装的CentOS 6.5网络设置为NAT模式时&#xff0c;怎么使用SecureCRT连接CentOS6.5系统&#xff1f; 一、查询 【VirtualBox Host-Only Network】虚拟网卡的网络配置 IP。 1、按键盘上WIN R 组合键&#xff0c;打开【运行】&#xff0c;输入【 ncpa.cpl 】&…

C0012.Clion改用VS编译器开发Qt界面

1.VS编译器添加 2.配置MSVC2019环境变量 3.各种问题报错与解决 问题描述 warning C4819&#xff1a;该文件包含不能在当前代码页(936)中表示的字符。解决办法 在CMakeLists.txt中添加如下代码 # 如下代码只在使用VS编译器时需要&#xff0c;使用mingw32编译器时需要注释掉 #…

利用Numpy实现全连接神经网络实验分析

一、实验要求 用 python 的 numpy 模块实现全连接神经网络。网络结构为一个输入层、一个隐藏层、一个输出层。隐藏层的激活函数为 Relu 函数&#xff0c;输出层的激活函数为 softmax 函数&#xff0c;损失函数为交叉熵。 二、实验目的 学会构建一个简单的全连接神经网络模型学…

鸿蒙网络管理模块01——HTTP与WebSocket请求数据

如果你也对鸿蒙开发感兴趣&#xff0c;加入“Harmony自习室”吧&#xff01;扫描下方名片&#xff0c;关注公众号&#xff0c;公众号更新更快&#xff0c;同时也有更多学习资料和技术讨论群。 1、概述 鸿蒙的网络管理模块主要提供以下功能&#xff1a; HTTP数据请求&#xff1…

影刀RPA实战:网页爬虫之电影数据

1.实战目标 电影自媒体是指个人或团队通过互联网平台&#xff0c;如微博、微信公众号、抖音、B站等&#xff0c;发布与电影相关的内容&#xff0c;包括但不限于电影评论、推荐、幕后制作揭秘、明星访谈等。这些内容旨在吸引电影爱好者&#xff0c;并与之互动&#xff0c;构建起…

十六字心传

中国文化传统中著名的“十六字心传”&#xff1a;“人心惟危&#xff0c;道心惟微&#xff1b;惟精惟一&#xff0c;允执厥中。 ”语出于《虞书大禹谟》。 人心与道心&#xff1a;人的人欲与天理的区别&#xff1b;所谓“人心惟危”&#xff0c;即是说人们的那种物欲情欲&…

【FPGA开发】Xilinx FPGA差分输入时钟的使用方法

正文 以前在使用ZYNQ的领航者ZYNQ7020进行FPGA学习时&#xff0c;它们使用的单端50M的输入时钟&#xff0c;在verlog代码编写上比较简单&#xff0c;而现在使用Alinx的AXU3EG开发板时&#xff0c;发现它使用的是200M的差分输入时钟&#xff0c;哪这个时候&#xff0c;输入时钟要…

pyecharts-快速入门

pyecharts文档&#xff1a;渲染图表 - pyecharts - A Python Echarts Plotting Library built with love. pyecharts-gallery文档&#xff1a;中文简介 - Document (pyecharts.org) 一、快速入门案例 from pyecharts.charts import Barbar Bar() bar.add_xaxis(["衬衫…

7-3 集合的运算-并、交、对称差

顺序表&#xff1a; #include <bits/stdc.h> using namespace std; int main() {int n;cin>>n;int *pnew int[n];for(int i0;i<n;i)cin>>p[i];int m;cin>>m;int *qnew int [m];for(int j0;j<m;j)cin>>q[j];int *bingnew int[nm];int *jia…

详细介绍:API 和 SPI 的区别

文章目录 Java SPI (Service Provider Interface) 和 API (Application Programming Interface) 的区别详解目录1. 定义和目的1.1 API (Application Programming Interface)1.2 SPI (Service Provider Interface) 2. 使用场景2.1 API 的应用场景2.2 SPI 的应用场景 3. 加载和调…

Elasticsearch基础_5.ES聚合功能

文章目录 一、数据聚合1.1、桶聚合1.1.1、单维度桶聚合1.1.2、聚合结果排序1.1.3、限定聚合范围 本文只记录ES聚合基本用法&#xff0c;后续有更复杂的需求可以查看相关书籍&#xff0c;如《Elasticsearch搜索引擎构建入门与实战》 一、数据聚合 聚合可以让我们极其方便的实现…

进程和线程之间的通用方式

进程之间的通信方式有哪些 进程间通信&#xff08;Inter-Process Communication, IPC&#xff09;是指不同进程之间传递信息和数据的机制。由于进程之间的内存空间是相互独立的&#xff0c;因此必须使用特定的通信方式来实现数据共享。 以下是常见的进程间通信方式&#xff1…

【前端开发入门】css快速入门

目录 引言一、css盒模型1. 盒模型概念2. 盒模型案例 二、css编写1. html文件内部编写1.1 标签style属性编写1.2 css选择器关联1.2.1 id选择器1.2.2 class选择器1.2.3 标签选择器1.2.4 css选择器作用域1.2.5 其他选择器1.2.6 各css选择器优先级 2. 单独维护css文件2.1 创建css文…

【韩顺平Java笔记】第6章:数组、排序和查找

文章目录 153. 回顾上节课内容154. 听懂和会做155. 数组的必要性156. 数组快速入门157. 数组使用1158. 数组使用2160. 数组使用3161. 数组注意事项161. 数组练习1162. 数组练习2163. 数组赋值机制1164. 数组赋值机制2165. 数组拷贝166. 数组翻转1168. 169. 数组扩容1,2170. 数组…

解决银河麒麟服务器操作系统中`/etc/bashrc`环境变量不生效的问题

解决银河麒麟服务器操作系统中/etc/bashrc环境变量不生效的问题 1、问题描述2、问题原因3、解决方法 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 在银河麒麟服务器操作系统中&#xff0c;有时你可能会遇到在/etc/bashrc文件中配置的环境…

VMware 设置静态IP

环境 os: centos 7vmware: 16.2.0 build-18760230 设置静态IP 不知道桥接模式和nat模式抽什么疯&#xff0c;忽然用不了了&#xff0c;虚拟机开机之后&#xff0c;本地ssh连接不上&#xff0c;ping 了一下&#xff0c;本机ping不通虚拟机。干脆参考网上的方法&#xff0c;直…

【网络安全 | Java代码审计】某Blog系统

未经许可,不得转载。 文章目录 公告处XSS评论处XSS添加友链处XSS文件上传处XSS公告处XSS 编辑公告处后端代码: 跟进updateNotice()方法: 继续跟进: 公告内容直接插入数据库,看看前端从数据库获取数据时有没有对数据做处理: noticeService 是一个服务层组件,负责业务逻辑…

【Verilog学习日常】—牛客网刷题—Verilog企业真题—VL74

异步复位同步释放 描述 题目描述&#xff1a; 请使用异步复位同步释放来将输入数据a存储到寄存器中&#xff0c;并画图说明异步复位同步释放的机制原理 信号示意图&#xff1a; clk为时钟 rst_n为低电平复位 d信号输入 dout信号输出 波形示意图&#xff1a; 输入描…

在线翻译界的4大宝藏,一站式解决语言难题!

现在全球化越来越厉害&#xff0c;语言根本就不是啥沟通的阻碍了。不管是搞学术研究、商务交流&#xff0c;还是平常学习&#xff0c;翻译工具都成了咱少不了的帮手。今天呢&#xff0c;我给大家推荐四款在 2024 年特别受推崇的邮件翻译神器&#xff0c;像百度在线翻译啥的。这…