学习笔记:I/O读操作

要运行下面的程序,首先得创建一个包含数字的文本文件。为此,可以用使用文本编辑器(如用于编写源代码的文本编辑器)。假设该文件为名scores.txt,包含的内容如下:

1
2
18 19 18.5 13.5 14 
16 19.5 20 18 12 18.5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <fstream>
#include <cstdlib>
const int SIZE = 60;
int main()
{
using namespace std;
char filename[SIZE];
ifstream inFile; //object for handing file input
cout<<"Enter name of data file: ";
cin.getline(filename,SIZE);
inFile.open(filename); //associate inFile with a file
if (!inFile.is_open()) //failed to open file
{
cout<<"Could not open the file "<<filename <<endl;
cout<<"Program terminating.\n";
exit(EXIT_FAILURE);
}
double value;
double sum = 0.0;
int count = 0; //number of items read
inFile >> value; //get first value
while (inFile.good()) //whiel input good and not at EOF
{
++count; //one more item read
sum+=value; //calculate running total
inFile>>value; // get next value
}
if (inFile.eof())
cout<<"End of file reached.\n";
else if (inFile.fail())
cout<<"Input terminated by data mismatch.\n";
else
cout<<"Input terminated for unknown reason.\n";
if (count == 0)
cout<<"No data processed.\n";
else
{
cout<<"Intem read: "<<cout<<endl;
cout<<"Sum: "<<sum<<endl;
cout<<"Average: "<<sum / count << endl;
}
inFile.close(); //finished with the file
return 0;
}

程序说明

该程序没有使用硬编码文件名,而是将用户提供的文件名存储到字符数组filename中,然后该数组用作open()的参数:

1
inFile.open(fielname);

检查文件是否被打开至关重要。下面是一些可能出问题的地方:指定的文件可能不存在;文件可能位于另一个目录(文件夹)中;访问可能拒绝;用户可能输错了文件名或省略了文件扩展名。很多初学者花了大量的时间检查文件读取循环的哪里出了问题后,最终却发现问题在于程序没有打开文件。检查文件是否被成功打开可避免这种精力放在错误地方的情况发生。
需要注意的是文件读取循环的正确设计。读取文件时,有几点需要检查。
首先,程序读取文件时不应超过EOF。如果最后一次读取数据时遇到EOF,方法eof()将返回true。
其次,程序可能遇到类型不匹配的情况。例如,下面程序期望文件中只包含数字。如果最后一次读取操作中发生了类型不匹配的情况,方法fail()将返回true(如果遇到EOF,该方法也将返回true)。
最后,可能出现意外的问题,如文件受损或硬件故障。如果最后一次读取文件时发生了这样的问题,方法bad()将返回true。不要分别检查这些情况,一种更简单的方法是使用good()方法,该方法在没有发生任何错误时返回true:

1
2
3
4
while (inFile.good())		//while input good and not at EOF
{
...
}

然后,可以使用其他方法来确定循环终止的真正原因:

1
2
3
4
5
6
if (inFile.eof())
cout<<"Enter of file reached.\n";
else if (inFiel.fail())
cout<<"Input terminated by data mismatch .\n";
else
cout << "Input terminated for unknown reason.\n";

这些代码紧跟在循环的后面,用于判断循环为何停止。由于eof()只能判断是否到达EOF,而fail()可用于检查EOF和类型不匹配,因此上述代码首先判断是否到达EOF。这样,如果执行到了else if 测试,便可排除EOF,因此,如果fail()返回true,便可断定导致循环终止的原因是类型不匹配
方法good()指出最后一次读取输入的操作是否成功,这一点至关重要。这意味着应该在执行读取输入的操作后,立刻应用这种测试。为此,一种标方法是,在循环之前(首次执行循环前)放置一条输入语句,并在循环的末尾(下次执行循环测试之前)放置另一条输入语句:

1
2
3
4
5
6
7
// standard file-reading loop design
inFile >> value; //get first value
while (inFile.good()) //while input good and not at EOF
{
//loop body goes here
inFile >> value; //get next value
}

鉴于以下事实,可以对上述代码进行精简:表达式inFile>>value的结果为inFiel,而在需要一个bool值的情况下,inFile的结果为inFile.good(),即true或false。
因此,可以将两条输入语句用一条用作循环测试的输入语句代替。也就是说,可以将上述循环结构替换为如下循环结构:

1
2
3
4
5
6
7
// abbreviated file-reading loop design
// omit pre-loop input
while (inFiel >> value) //read and test for success
{
//loop body goes here
// cmit end-of-loop input
}

这种设计仍然遵循了在测试前进行读取的规则,因此要计算表达式inFile >> value的值,程序必须首先试图将一个数字读取到value中。

本文标题:学习笔记:I/O读操作

文章作者:water

发布时间:2018年07月18日 - 15:20:52

最后更新:2018年07月18日 - 16:03:50

原始链接:http://9cat.top/2018/07/18/学习笔记:I-O读操作/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

------ 本文结束------
分享
分享