【C++】IO库 : IO类,文件输入输出,string流

2023-10-26

前面已经在用的IO库设施

  • istream:输入流类型,提供输入操作。
  • ostream:输出流类型,提供输出操作
  • cin:一个istream对象,从标准输入读取数据。
  • cout:一个ostream对象,向标准输出写入数据。
  • cerr:一个ostream对象,向标准错误写入消息。
  • >>运算符:用来从一个istream对象中读取输入数据。
  • <<运算符:用来向一个ostream对象中写入输出数据。
  • getline函数:从一个给定的istream对象中读取一行数据,存入到一个给定的string对象中。

IO类

  • iostream头文件:从标准流中读写数据,istream,ostream
  • fstream头文件:从文件中读写数据,ifstream,ofstream
  • sstream头文件:从字符串中读写数据,istringstream,ostringstream

IO对象不能拷贝赋值

由于不能拷贝IO对象,因此不能将 形参 或 返回类型 设置为 流类型。进行 IO 操作的函数通常以 引用方式 传递和 返回流。读写一个IO对象会改变其状态,因此 传递和返回的引用不能用const

  • 1.IO对象不能存在容器里.
  • 2.形参和返回类型也不能是流类型。
  • 3.形参和返回类型一般是流的引用
  • 4.读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的。

条件状态

状态 解释
strm:iostate 是一种机器无关的类型,提供了表达条件状态的完整功能
strm:badbit 用来指出流已经崩溃
strm:failbit 用来指出一个IO操作失败了
strm:eofbit 用来指出流到达了文件结束
strm:goodbit 用来指出流未处于错误状态,此值保证为零
s.eof() 若流seofbit置位,则返回true
s.fail() 若流sfailbit置位,则返回true
s.bad() 若流sbadbit置位,则返回true
s.good() 若流s处于有效状态,则返回true
s.clear() 将流s中所有条件状态位复位,将流的状态设置成有效,返回void
s.clear(flags) 将流s中指定的条件状态位复位,返回void
s.setstate(flags) 根据给定的标志位,将流s中对应的条件状态位置位,返回void
s.rdstate() 返回流s的当前条件状态,返回值类型为strm::iostate

上表中,strm是一种IO类型,(如istream), s是一个流对象。

管理输出缓冲

  • 每个输出流都管理一个缓冲区,用来保存程序读写的数据。文本串可能立即打印出来,也可能被操作系统保存在缓冲区内,随后再打印。

  • 刷新(即,数据真正写到输出设备或文件)缓冲区的IO操纵符

    • endl:输出一个换行符并刷新缓冲区
    • flush:刷新流,但不添加任何字符
    • ends:在缓冲区插入空字符null,然后刷新
    • unitbuf:告诉流接下来每次操作之后都要进行一次flush操作。
    • nounitbuf:回到正常的缓冲方式

文件输入输出

  • 头文件fstream定义了三个类型来支持文件IO:
    • ifstream从一个给定文件读取数据。
    • ofstream向一个给定文件写入数据。
    • fstream可以读写给定文件。

fstream特有的操作

操作 解释
fstream fstrm; 创建一个未绑定的文件流。
fstream fstrm(s); 创建一个文件流,并打开名为s的文件,s可以是string也可以是char指针
fstream fstrm(s, mode); 与前一个构造函数类似,但按指定mode打开文件
fstrm.open(s) 打开名为s的文件,并和fstrm绑定
fstrm.close() 关闭和fstrm绑定的文件
fstrm.is_open() 返回一个bool值,指出与fstrm关联的文件是否成功打开且尚未关闭

上表中,fstream是头文件fstream中定义的一个类型,fstrm是一个文件流对象。

文件模式

文件模式 解释
in 以读的方式打开
out 以写的方式打开
app 每次写操作前均定位到文件末尾
ate 打开文件后立即定位到文件末尾
trunc 截断文件
binary 以二进制方式进行IO操作。

string流

  • 头文件sstream定义了三个类型来支持内存IO:
    • istringstreamstring读取数据。
    • ostringstreamstring写入数据。
    • stringstream可以读写给定string

stringstream特有的操作

操作 解释
sstream strm 定义一个未绑定的stringstream对象
sstream strm(s) s初始化对象
strm.str() 返回strm所保存的string的拷贝
strm.str(s) s拷贝到strm中,返回void

上表中sstream是头文件sstream中任意一个类型。s是一个string

书中演示demo使用

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

typedef struct PersonInfo
{
	string name;
	vector<string> phones;
}p;

int main() {
	string line, word;
	vector<p> people;
	while (getline(cin, line))
	{
		p info;
		istringstream record(line);
		record >> info.name;
		while (record >> word)
			info.phones.push_back(word);
		people.push_back(info);
	}


	for (auto i : people)
	{
		cout << i.name << endl;
		for (auto j : i.phones)
			cout << j << "   ";
		cout << endl;
	}
	return 0;
}

练习

练习8.1

编写函数,接受一个istream&参数,返回值类型也是istream&。此函数须从给定流中读取数据,直至遇到文件结束标识时停止。它将读取的数据打印在标准输出上。完成这些操作后,在返回流之前,对流进行复位,使其处于有效状态。

解:

std::istream& func(std::istream &is)
{
    std::string buf;
    while (is >> buf)
        std::cout << buf << std::endl;
    is.clear();
    return is;
}

练习8.2

测试函数,调用参数为cin

解:

#include <iostream>
using std::istream;

istream& func(istream &is)
{
    std::string buf;
    while (is >> buf)
        std::cout << buf << std::endl;
    is.clear();
    return is;
}

int main()
{
    istream& is = func(std::cin);
    std::cout << is.rdstate() << std::endl;
    return 0;
}

测试

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

istream& f1(istream& is)
{
	int s;
	while (is >> s)
	{
		cout << s << endl;
	}
	return is;
}

istream& f2(istream& is)
{
	int s;
	while (is >> s)
	{
		cout << s << endl;
	}
	is.clear();
	return is;
}

int main()
{
	istream& is = f1(cin);
	cout << is.rdstate() << endl;
	istream& is2 = f2(cin);
	cout << is2.rdstate() << endl;
	return 0;
}

练习8.3

什么情况下,下面的while循环会终止?

while (cin >> i) /*  ...    */

badbitfailbiteofbit 的任一个被置位,那么检测流状态的条件会失败。

练习8.4

编写函数,以读模式打开一个文件,将其内容读入到一个stringvector中,将每一行作为一个独立的元素存于vector中。

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

void ReadFileToVec(const string& filename, vector<string>& vec)
{
	ifstream ifs(filename);
	if (ifs)
	{
		string buf;
		while (getline(ifs, buf))
			vec.push_back(buf);
	}
}

练习8.5

重写上面的程序,将每个单词作为一个独立的元素进行存储。

void ReadFileToVec(const string& fileName, vector<string>& vec)
{
    ifstream ifs(fileName);
    if (ifs)
    {
        string buf;
        while (ifs >> buf)
            vec.push_back(buf);
    }
}

练习8.10

编写程序,将来自一个文件中的行保存在一个vector中。然后使用一个istringstreamvector读取数据元素,每次读取一个单词。

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
using namespace std;

int main()
{
	//将来自一个文件的行保存到vector中
	ifstream ifs("hello.txt");
	if (!ifs)
	{
		cerr << "no data ?" << endl;
		return -1;
	}

	vector<string> vecline;
	string line;
	while(getline(ifs, line))
		vecline.push_back(line);
	ifs.close();

	//从vector读取元素,每次只读一个单词
	for (auto &s : vecline)
	{
		istringstream iss(s);
		string word;
		while (iss >> word)
			cout << word << endl;
	}

	return 0;
}

练习8.11

本节的程序在外层while循环中定义了istringstream对象。如果record对象定义在循环之外,你需要对程序进行怎样的修改?重写程序,将record的定义移到while循环之外,验证你设想的修改方法是否正确。

解:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using std::vector; using std::string; using std::cin; using std::istringstream;

struct PersonInfo {
    string name;
    vector<string> phones;
};

int main()
{
    string line, word;
    vector<PersonInfo> people;
    istringstream record;
    while (getline(cin, line))
    {
        PersonInfo info;
        record.clear();
        record.str(line);
        record >> info.name;
        while (record >> word)
            info.phones.push_back(word);
        people.push_back(info);
    }
    
    for (auto &p : people)
    {
        std::cout << p.name << " ";
        for (auto &s : p.phones)
            std::cout << s << " ";
        std::cout << std::endl;
    }
    
    return 0;
}

练习8.12

我们为什么没有在PersonInfo中使用类内初始化?

解:

因为这里只需要聚合类就够了,所以没有必要在PersionInfo中使用类内初始化。

练习8.13

电话号码程序

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
using namespace std;

struct PersonInfo {
	string name;
	vector<string> phones;
};

bool valid(const string& str)
{
	return isdigit(str[0]);
}

string format(const string& str)
{
	return str.substr(0, 3) + "-" + str.substr(3, 3) + "-" + str.substr(6);
}

int main()
{
	//从文件中读取信息存入vector容器
	ifstream ifs("phone.txt");
	if (!ifs)
	{
		cerr << "no phone numbers ? " << endl;
		return -1;
	}

	vector<PersonInfo> people;
	string line, word;
	istringstream record;

	while (getline(ifs, line))
	{
		PersonInfo info;
		record.clear();
		record.str(line);
		record >> info.name;
		while (record >> word)
		{
			info.phones.push_back(word);
		}
		people.push_back(info);
	}

	//逐个验证电话号码 并 改变其格式
	for (const auto& entry : people)   //对people中的每一项
	{
		//每个循环创建的对象
		ostringstream formatted, badnums;
		//对每个数
		for (const auto& nums : entry.phones)
		{
			if (!valid(nums))
			{
				badnums << " " << nums;
				//将数的字符串形式存入badnums
			}
			else
			{
				//将格式化的字符串写入formatted
				formatted << " " << format(nums);
			}
		}

		//没有错误的数
		if (badnums.str().empty())
		{
			cout << entry.name << " "
				<< formatted.str() << endl;
		}
		else
		{
			//打印名字和错误的数
			cerr << "input error: " << entry.name
				<< " invalid number(s)" << badnums.str() << endl;
		}
	}

	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【C++】IO库 : IO类,文件输入输出,string流 的相关文章

  • C++:无法使用scoped_allocator_adaptor传播polymorphic_allocator

    我有一个vector
  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 初始化变量的不同方式

    在 C 中初始化变量有多种方法 int z 3 与 int 相同z 3 Is int z z 3 same as int z z 3 您可以使用 int z z 3 Or just int z 3 Or int z 3 Or int z i
  • 更改窗口的内容 (WPF)

    我创建了一个简单的 WPF 应用程序 它有两个 Windows 用户在第一个窗口中填写一些信息 然后单击 确定 这会将他们带到第二个窗口 这工作正常 但我试图将两个窗口合并到一个窗口中 这样只是内容发生了变化 我设法找到了这个更改窗口内容时
  • .NET 选项将视频文件流式传输为网络摄像头图像

    我有兴趣开发一个应用程序 它允许我从 xml 构建视频列表 包含视频标题 持续时间等 并将该列表作为我的网络摄像头流播放 这意味着 如果我要访问 ustream tv 或在实时通讯软件上激活我的网络摄像头 我的视频播放列表将注册为我的活动网
  • 用 C 实现 Unix shell:检查文件是否可执行

    我正在努力用 C 语言实现 Unix shell 目前正在处理相对路径的问题 特别是在输入命令时 现在 我每次都必须输入可执行文件的完整路径 而我宁愿简单地输入 ls 或 cat 我已经设法获取 PATH 环境变量 我的想法是在 字符处拆分
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new

随机推荐

  • vulnstack域环境靶场(四)

    环境搭建 进入Ubuntu的web虚拟机 ubuntu为我们的web环境 其中的web环境需要手动开启 全部为docker环境 需要启动的环境分别为 s2 045 CVE 2017 12615 cve 2018 12613 启动方法如下 s
  • 32位算术逻辑运算单元alu设计_算术移位和逻辑移位详解

    大部分的C编译器 用移位的方法得到代码比调用乘除法子程序生成的代码效率高 最近在看Java源码的时候 看到了一些位运算的操作 特意在整理了一下移位运算 不整理不知道 一整理吓一跳 那就随着一起看下去吧 移位运算是将数值向左向右移动 对于十进
  • Centos 6.5下C连接MySQL测试

    Centos 6 5下C连接MySQL测试 include
  • Spark sql的简单使用

    目录 加载依赖 spark sql简单入门 Spark sql简单应用 应用配置 读取文件 读取文本文件并展示数据 show 将数据完全显示 读取json文件 读取jdbc文件 读取压缩格式的文件 将数据以压缩格式存储 parquet或者o
  • hdlc协议解码的四种方法

    hdlc协议规定了 在hdlc中不能出现连续的6个1 因为这是hdlc帧的分割标志 因此在编码的时候每遇到5个连续的1就插入0 因此解码时就需要碰到5个连续的1就要去掉后面的0 而在我们的计算机中都是以整数字节描述信息 因此造成了用pc解h
  • 【uni-app教程】三、 UniAPP 生命周期

    三 UniAPP 生命周期 学习一个工具的目的核心是什么 是为了解决核心业务逻辑问题 业务逻辑很多时候简单的解释一句话 在合适的时机干合适的事情 OK 什么是合适的时机呢 简单的说 页面话行过程中 各个阶段的回调孟数就是页面中的时机 我们也
  • 如何在C语言中巧妙地避免使用if语句?

    近期在做CSAPP的homework时碰到一些题目 代码中不允许使用if语句 于是聪明的同学们想出了一个巧妙的办法 利用C语言中与运算符 的 短路 特性完成了这个任务 例如 如果C语言原语句是 if x gt y a x 为了去掉这个if
  • yolov4 darknet安装笔记

    yolov4 darknet安装笔记 cuda cudnn安装 cuda 10 0下载及安装 运行安装包 运行补丁包 建立软链接 添加环境变量 对应版本cudnn下载及安装 darknet GPU版本安装 Makefile修改 nvcc 路
  • LA@二次型标准形@标准化问题介绍和合同对角化@二次型可标准化定理

    文章目录 二次型的标准形 标准形的矩阵式 标准化问题 合同对角化 二次型标准化分析 二次型可标准化定理 正交相似角度证明 配方角度证明 case1 方法1 case2 方法2 case2 case3 二次型的标准形 如果二次型只含有变量的平
  • Kerberos安全认证-连载12-Kafka Kerberos安全配置及访问

    目录 1 Kafka配置Kerberos 2 客户端操作Kafka 3 Java API操作Kafka 4 StructuredStreaming操作Kafka 5 Flink 操作Kafka 技术连载系列 前面内容请参考前面连载11内容
  • Dictionary的基本用法

    1 创建泛型哈希表 然后加入元素 Dictionary
  • 宋分题——Java实现登录窗口 和 信息录入窗口

    编写一个登录窗口 密码输入采用密码框 输入密码显示为 当输入用户名admin密码123的时候点击确定跳转到学生信息录入窗口界面 其他输入显示用户名密码错误 点击取消退出运行 import java awt import java awt e
  • RANSAC基本原理

    计算机视觉基本原理 RANSAC 1 RANSAC简介 2 基本思想 3 范例 4 迭代次数推导 Reference 1 计算机视觉基本原理 RANSAC 1 RANSAC简介 RANSAC RAndom SAmple Consensus
  • Ubuntu 怎么开放端口

    要在 Ubuntu 中开放端口 需要使用 ufw 防火墙 首先 确保 ufw 已经安装 如果尚未安装 可以使用以下命令进行安装 sudo apt get install ufw 然后 使用以下命令开启 ufw 防火墙 sudo ufwena
  • 玩转代码

    前言 在面试的时候 经常会遇到一道经典的面试题 如何优化网页加载速度 常规的回答中总会有一条 把 css 文件放在页面顶部 把 js 文件放在页面底部 那么 为什么要把 js 文件放在页面的最底部呢 我们先来看下这段代码
  • Android 字体加载

    1 Font配置文件 位于frameworks base data fonts system fonts xml fallback fonts xml 文件结构
  • 【LVM技术创建磁盘和磁盘配额】

    文章目录 一 知识点 二 实验 1 创建物理卷 2 卷组打包命名形成逻辑硬盘 3 创建逻辑卷 4 格式化 创建文件系统 5 挂载 三 扩容逻辑卷 四 给卷组继续添加空间 五 磁盘配额 一 知识点 LVM技术特点 1 打破分区只能单个挂载 单
  • Ubuntu下分别用gcc和makefile编译C语言

    Ubuntu下分别用gcc和makefile编译C语言 1 编写C文件 2 gcc编译C文件 3 makefile编译C文件 3 1 创建makefile文件 3 2 编译makefile文件 4 总结 在Windows环境下通过虚拟机软件
  • RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED

    问题 调用显卡时 出现RuntimeError cuDNN error CUDNN STATUS NOT INITIALIZED 问题分析 出现这种问题 一般是因为cuda cudnn 显卡驱动 torch版本不匹配造成的 解决 1 第一个
  • 【C++】IO库 : IO类,文件输入输出,string流

    前面已经在用的IO库设施 istream 输入流类型 提供输入操作 ostream 输出流类型 提供输出操作 cin 一个istream对象 从标准输入读取数据 cout 一个ostream对象 向标准输出写入数据 cerr 一个ostre