【C++】学习笔记二十八——文件输入/输出

来源:互联网 发布:java小写字母转大写 编辑:程序博客网 时间:2024/05/16 14:37

文件输入输出

文本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)。

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

  1. 包含头文件fstream
  2. 创建一个ofstream对象
  3. 将该ofstream对象同一个文件关联起来
  4. 像使用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。

0 0
原创粉丝点击