首页 > 编程 > C++ > 正文

【C++ Primer plus 第6版】学习笔记二十八——文件输入/输出

2019-11-08 01:35:40
字体:
来源:转载
供稿:网友

文件输入输出

文本I/O和文本文件

  使用cin进行输入时,程序将输入视为一系列的字节,其中每个字节都被解释为字符编码。不管目标数据类型是什么,输入一开始都是字符数据——文本数据。然后,cin对象负责将文本转换为其他类型。      假设有如下示例输入行:

38.5 19.2

来看一下使用不同数据类型的变量来存储时,cin是如何处理输入行的。    char类型

char ch;cin >> ch;

输入行中的第一个字符被赋给ch。在这里,第一个字符是数字3,其字符编码(二进制)被存储在变量ch中。输入和目标变量都是字符,因此不需要进行转换。注意这里存储的是字符3的编码。执行上述输入语句后,输入队列中的下一个字符为字符8,下一个输入操作将对其进行处理。    int类型

int n;cin >> n;

在这种情况下,cin将不断读取,直到遇到非数字字符。也就是说,它将读取3和8,这样句点将成为输入队列中的下一个字符。cin通过计算发现,这两个字符对应数值38,因此将38的二进制字符复制到变量n中。   double类型

double x;cin >> x;

在这种情况下,cin将不断读取,直到遇到第一个不属于浮点数的字符。也就是说,cin读取3、8、句点和5,使得空格成为输入队列中的下一个字符。cin通过计算发现,这四个字符对应于数值38.5,因此将38.5的二进制编码(浮点格式)复制到变量x中。

   char数组

char Word[50];cin >> word;

在这种情况下,cin将不断读取,直到遇到空白字符。也就是说,它读取3、8、句点和5,使得空格成为输入队列中下一个字符。然后,cin将这4个字符的编码存储到数组word中,并在末尾加上一个空字符。这里不需要进行任何转换。

最后,来看一下另一种使用char数组来存储输入的情况:

char word[50];cin.getline(word,50);

在这种情况下,cin将不断读取,直到遇到换行符(示例输入行少于50个字符)。所有字符都被存储到数组word中,并在末尾加上一个空字符。换行符被丢弃,输入队列中的下一个字符是下一行中的第一个字符。这里不需要进行任何转换。    本文讨论的文件I/O仅适用于文本文件。


写入到文本文件中

  对于文件输入,C++使用类似于cout的东西。使用cout要注意以下几点:

必须包含头文件iostream头文件iostream定义了一个用于处理输出的ostream类头文件iostream声明了一个名为cout的ostream变量(对象)必须指明名称空间std

可以结合使用cout和运算符<<来显示各种类型的数据

  文件输出与此极其类似:

必须包含头文件fstream头文件fstream定义了一个用于处理输出的ofstream类需要声明一个或多个ofstream类(对象),并以自己喜欢的方式对其进行命名,条件是遵守常用的命名规则必须指明名称空间std需要将ofstream对象与文件关联起来。为此,方法之一是使用open()方法使用完文件后,应使用方法close()将其关闭

可结合使用ofstream对象和运算符<<来输出各种类型的数据

  注意:虽然头文件iostream提供了一个预先定义好的名为cout的ostream对象,但我们必须声明自己的ofstream对象,为其命名,并将其同文件关联起来:

声明对象:

ofstream outFile;ofstream fout;

将这种对象与特定的文件关联起来:

outFile.open("fish.txt"); //outFile用于写入fish.txtchar filename[50];cin >> filename; //用户指定一个名字fout.open(filename); //fout用于读取特定文件

  注意,方法open()接受一个C-风格字符串作为参数,这可以是一个字面字符串,也可以是存储在数组中的字符串。

下面演示了如何使用这种对象:

double wt = 125.8;outFile << wt; //将一个数字写入fish.txtchar line[81] = "Objects are closer than they appear.";fout << line << endl; //写入一行文本

重要的是,声明一个ofstream对象并将其同文件关联起来后,便可以像使用cout那样使用它。所有可用于cout的操作和方法(如<<、endl和setf())都可用于ofstream对象(如前述示例中的outFile和fout)。

使用文件输出的主要步骤如下:

包含头文件fstream创建一个ofstream对象将该ofstream对象同一个文件关联起来像使用cout那样使用该ofstream对象

程序6.15

#include<iostream>#include<fstream>int main(){ using namespace std; char automobile[50]; int year; double a_PRice; double d_price; ofstream outFile; outFile.open("carinfo.txt"); cout << "Enter the make and model of automobile: "; cin.getline(automobile, 50); cout << "Enter the model year: "; cin >> year; cout << "Enter the orginal asking price: "; cin >> a_price; d_price = 0.913 * a_price; cout << fixed; cout.precision(2); cout.setf(ios_base::showpoint); cout << "Make and model: " << a_price << endl; cout << "Year: " << year << endl; cout << "Was asking $" << a_price << endl; cout << "Now asking $" << d_price << endl; outFile << fixed; outFile.precision(2); outFile.setf(ios_base::showpoint); outFile << "Make and model: " << a_price << endl; outFile << "Year: " << year << endl; outFile << "Was asking $" << a_price << endl; outFile << "Now asking $" << d_price << endl; outFile.close(); system("pause"); return 0;}

程序使用完文件后,应使用close()将其关闭。close()不需要文件名作为参数,因为outFile已经同特定的文件关联起来。

程序运行之前,carinfo.txt并不存在,这种情况下,open()将新建一个名为carinfo.txt的文件。如果文件carinfo.txt已经存在,open()将清空该文件,再将新的输出写入到该文件中。


读取文本文件

读取文本文件是基于控制台输入的。 控制台输入涉及以下方面:

必须包含头文件iostream头文件iostream定义了一个用于处理输入的istream类头文件iostream声明了一个名为cin的istream对象必须指明名称空间std,using namespace std可以结合使用cin和运算符>>来读取各种类型的数据可以使用cin和get()来读取一个字符,使用cin和getline()来读取一行字符对象cin本身被用作测试条件时,如果最后一个读取操作成功,将被转换为bool值true,否则为false

文件输出:

必须包含头文件fstream头文件fstream定义了一个用于处理文件读取的ifstream类需要声明一个或多个ifstream对象,并以合法的方式对其进行命名必须指明名称空间std,using namespace std需要将ifstream对象与文件关联起来,一种方法是使用open()使用完文件后,应使用close()将文件关闭可以结合使用ifstream对象和运算符>>来读取各种类型的数据可以使用ifstream对象和get()来读取一个字符,使用ifstream对象和getline()来读取一行字符可以结合使用ifstream对象和eof()、fail()等方法来判断输入是否成功ifstream对象本身被用作测试条件时,如果最后一个读取操作成功,将被转换为bool值true,否则为false

声明ifstream对象:

ifstream inFile;ifstream fin;

将ifstream对象与特定的文件关联起来:

inFile.open("bowling.txt");char filename[50];cin >> filename;fin.open(filename);

  注意,方法open()接受一个C-风格字符串作为参数,这可以是一个字面字符串,也可以是存储在数组中的字符串。

使用ifstream对象:

double wt;inFile >> wt;char line[81];fin.getline(line, 81);

重要的是,声明一个ifstream对象并将其同文件关联起来后,便可以像使用cin那样使用它。所有可用于cin的操作和方法都可用于ifstream对象(如前述示例中的inFile和fin)。

如果试图打开一个不存在的文件作为输入,将导致后面使用ifstream对象进行输入时失败。检查文件是否被成功打开的方法是使用is_open():

inFile.open("bowling.txt");if (!inFile.is_open()){ exit(EXIT_FAILURE);}

函数exit()的原型是在头文件cstdlib中定义的,在该头文件中,还定义了一个用于同操作系统通信的参数值EXIT_FAILURE。函数exit()终止程序。

程序6.16

#include<iostream>#include<fstream>#include<cstdlib>const int SIZE = 60;int main(){ using namespace std; char filename[SIZE]; ifstream inFile; cout << "Enter name of data file: "; cin.getline(filename, SIZE); inFile.open(filename); if (!inFile.is_open()) { cout << "Could not open the file " << filename << endl; cout << "Program terminating./n"; exit(EXIT_FAILURE); } double value; double sum = 0.0; int count = 0; inFile >> value; while (inFile.good()) { ++count; sum += value; inFile >> 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 reson./n"; if (count == 0) cout << "No data processed./n"; else { cout << "Items read: " << count << endl; cout << "Sum: " << sum << endl; cout << "Average: " << sum / count << endl; } inFile.close(); system("pause"); return 0;}

检查文件是否被成功打开至关重要。

good()在没有任何错误发生时返回true。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选