当前位置: 首页 > news >正文

C++ primer plus 第17 章 输入、输出和文件:文件输入和输出02:流状态检查和is_open():打开多个文件:命令行处理技术

C++ primer plus 第17 章 输入、输出和文件:文件输入和输出01

17.4.2 流状态检查和is_open()

17.4.3 打开多个文件

17.4.4命令行处理技术

程序清单17.17 count.cpp


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • C++ primer plus 第17 章 输入、输出和文件:文件输入和输出01
  • 17.4.2 流状态检查和is_open()
  • 17.4.3 打开多个文件
  • 17.4.4命令行处理技术
  • 程序清单17.17 count.cpp
  • 17.4.2 流状态检查和is open()
  • 17.4.3 打开多个文件
  • 17.4.4命令行处理技术
  • 程序清单17.17 count.cpp


17.4.2 流状态检查和is open()

C++文件流类从iosbase 类那里继承了一个流状态成员。正如前面指出的,该成员存储了指出流状态的信息:一切顺利、已到达文件尾、I/0 操作失败等。如果一切顺利,则流状态为零(没有消息就是好消息)。其他状态都是通过将特定位设置为1来记录的。文件流类还继承了iosbase 类中报告流状态的方法,表17.4对这些方法进行了总结。可以通过检查流状态来判断最后一个流操作是否成功。对于文件流,这包括检查试图打开文件时是否成功。例如,试图打开一个不存在的文件进行输入时,将设置ilbit位,因此可以这样进行检查:

fin.open(argv[file]):
if (fin.fail())// open attempt failed
{
...
}

由于 ifstrcam 对象和 istrcam 对象一样,被放在需要 bool类型的地方时,将被转换为 bool值,因此您也可以这样做:

fin.open(argvlfile]);
if (!fin)//open attempt failed
{
...
}


然而,较新的C++实现提供了一种更好的检查文件是否被打开的方法–is_open()方法:

if(!fin.is open())//open attempt failed
{
...
}

这种方式之所以更好,是因为它能够检测出其他方式不能检测出的微妙问题,接下来的“警告”将讨论这一点。
警告:以前,检查文件是否成功打开的常见方式如下:

if(fin.fail())...// failed to open
if(!fin.good())...// failed to open
if (!fin)...

//failed to openfin 对象被用于测试条件中时,如果 fin.good()为fàlsc,将被转换为falsc;否则将被转换为 tnue。因此上面三种方式等价。然而,这些测试无法检测到这样一种情形:试图以不合适的文件模式(参见本章后面的“文件模式”一节)打开文件时失败。方法is_open( )能够检测到这种错误以及 good()能够检测到的错误然而,老式C++实现没有is_open()。

17.4.3 打开多个文件

程序可能需要打开多个文件。打开多个文件的策略取决于它们将被如何使用。如果需要同时打开两个文件,则必须为每个文件创建一个流。例如,将两个排序后的文件拼接成第三个文件的程序,需要为两个输入文件创建两个 ifstream 对象,并为输出文件创建一个 ofstream 对象。可以同时打开的文件数取决于操
作系统。然而,可能要依次处理一组文件。例如,可能要计算某个名称在10个文件中出现的次数。在这种情况下,可以打开一个流,并将它依次关联到各个文件。这在节省计算机资源方面,比为每个文件打开一个流的效率高。使用这种方法,首先需要声明一个istream对象(不对它进行初始化),然后使用 open( )方法将这个流与文件关联起来。例如,下面是依次读取两个文件的代码:

ifstream fin;//ereate stream using default construetor
fin.open("fat.txt");//associate stream with fat.txt file
...
fin.close();//terminate association with fat.txt
fin.clear();//reset fin (may not be needed)
fin.open("rat.txt”);//associate stream with rat.txt file
...// do stuff
...
fin.close();

稍后将介绍一个例子,但先来看这样一种将一系列文件输入给程序的技术,即让程序能够使用循环来处理文件。

17.4.4命令行处理技术

文件处理程序通常使用命令行参数来指定文件。命令行参数是用户在输入命令时,在命令行中输入的参数。例如,要在UNIX或Linux系统中计算文件包含的字数,可以在命令行提示符下输入下面的命令:
wc reportl report2 report3其中,wc是程序名,report1、report2和report3 是作为命令行参数传递给程序的文件名。C++有一种让在命令行环境中运行的程序能够访问命令行参数的机制,方法是使用下面的main()函数:

int main(int argc,char *argv])

argc为命令行中的参数个数,其中包括命令名本身。argv变量为一个指针,它指向一个指向char 的指针。这过于抽象,但可以将 argv看作一个指针数组,其中的指针指向命令行参数,argv[0]是一个指针,指向存储第一个命令行参数的字符串的第一个字符,依此类推。也就是说,argv[0]是命令行中的第一个字符串,依此类推。例如,假设有下面的命令行:
we reportl report2 report3
则argc为4,argv[0]为wc,argv[1]为reportl,依此类推。下面的循环将把每个命令行参数分别打印在单独一行上:

for (int i=l;i < argc; i++)
cout << argvli]<< endl;

以i-1开头将只打印命令行参数:以i=0开头将同时打印命令名。当然,命令行参数与命令行操作系统(如 Windows命令提示符模式、UNIX和Linux)紧密相关。其他程序也可能允许使用命令行参数。
很多 WindowsIDE(集成开发环境)都有一个提供命令行参数的选项。通常,必须选择一系列菜单,才能打开一个可以输入命令行参数的对话框。具体的步骤随厂商和升级版本而异,因此请查看文档。
很多 WindowsIDE都可以生成可执行文件,这些文件能够在 Windows 命令提示符模式下运行。
程序清单 17.17结合使用命令行技术和文件流技术,来计算命令行上列出的文件包含的字符数。

程序清单17.17 count.cpp

// count.cpp -- counting characters in a list of files
#include <iostream>
#include <fstream>
#include <cstdlib>          // or stdlib.h
int main(int argc, char * argv[])
{using namespace std;if (argc == 1)          // quit if no arguments{cerr << "Usage: " << argv[0] << " filename[s]\n";exit(EXIT_FAILURE);}ifstream fin;              // open streamlong count;long total = 0;char ch;for (int file = 1; file < argc; file++){fin.open(argv[file]);  // connect stream to argv[file]if (!fin.is_open()){cerr << "Could not open " << argv[file] << endl;fin.clear();continue;}count = 0;while (fin.get(ch))count++;cout << count << " characters in " << argv[file] << endl;total += count;fin.clear();           // needed for some implementationsfin.close();           // disconnect file}cout << total << " characters in all files\n";return 0; 
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python配置镜像
  • 【代理模式AOP】2. @Aspect的代码实战(比较Cglib和动态JDK)
  • 【STM32】USART串口和I2C通信
  • 【Canvas与艺术】黄色立体感放射光芒五角星
  • MATLAB优化模型(3)
  • Python新手错误集锦(PyCharm)
  • Django学习-数据迁移与数据导入导出
  • BIMRender渲染器插件上线 |一款免费的模型实时渲染插件
  • AI在医学领域:使用眼底图像和基线屈光数据来定量预测近视
  • 浅谈面向数据报的协议-UDP协议
  • 一文带你快速了解——LVS负载均衡集群
  • [Unity]在场景中随机生成不同位置且不重叠的物体
  • C#-了解ORM框架SqlSugar并巧妙使用(附相关数据库工具)
  • 数据结构——排序(2):选择排序+交换排序
  • 算法力扣刷题记录 六十九【动态规划基础及509. 斐波那契数】
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • [译]如何构建服务器端web组件,为何要构建?
  • 【刷算法】从上往下打印二叉树
  • 4个实用的微服务测试策略
  • Android组件 - 收藏集 - 掘金
  • E-HPC支持多队列管理和自动伸缩
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • Java,console输出实时的转向GUI textbox
  • Java教程_软件开发基础
  • spring + angular 实现导出excel
  • ViewService——一种保证客户端与服务端同步的方法
  • vue自定义指令实现v-tap插件
  • 闭包--闭包作用之保存(一)
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 关于 Cirru Editor 存储格式
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 我从编程教室毕业
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (二)丶RabbitMQ的六大核心
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (算法二)滑动窗口
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)setTimeout 和 setInterval 的区别
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .cn根服务器被攻击之后
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .net 7 上传文件踩坑
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET 回调、接口回调、 委托
  • .NET 依赖注入和配置系统
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET分布式缓存Memcached从入门到实战
  • .NET值类型变量“活”在哪?
  • @31省区市高考时间表来了,祝考试成功
  • @Not - Empty-Null-Blank
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择
  • [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)