文件I/O语句小结
假期学习了一些c++语法知识,笔记发出来给自己做个总结。
本例假定输入来自infile.dat文件,输出发送到outfile.dat文件
- 在程序文件中添加以下include预编译指令:
#include <fstream> // 用于文件I/O
#include <iostream> // 用于cout
#include <cstdlib> // 用于exit
- 为输入流选择流名称(如inStream),声明为ifstream类型的变量;为输出文件选择流名称(如outStream),声明为ofstream类型的变量。
using namespace std;
ifstream inStream;
ofstream outStream;
- 将外部文件名作为实参,调用open函数将每个流都连接到文件。记住用成员函数fail测试open调用是否调用成功。
inStream.open("infile.dat");
if (inStream.fail()){
cout << "Input file opening failed.\n";
exit(1);
}
outStream.open("outfile.dat");
if (outStream.fail()){
cout <<"Output file opening failed.\n";
exit(1);
}
- 就像使用cin从键盘获取输入一样,使用inStream流从Infile.dat文件获取输入,如下:
inStream >> someVariable >> someOtherVariable;
- 就像使用cout将输入发送到屏幕一样,使用outStream流将输出发送到outfile.dat文件,如下所示:
outStream << "someVariable =" << someVariable << endl;
- 使用close函数关闭流
inStream.close();
outStream.close();
- 要将数据追加到文件尾,使其位于文件原有内容之后,应该像下面这样打开文件
outputStream.open(Filename,ios::app);
// examle
ofstream OutStream;
outStream.open("Important.txt", ios::app);
用流函数格式化输出
对程序输出的布局进行调整称为对输出进行格式化,可为任何输出流使用这些格式化命令。
outStream.setf(ios::fixed);
outStream.setf(ios::showpoint);
outStream.precision(2);
成员函数precision
每个输出流都有名为precision的成员函数。程序一旦为outStream流执行了上述precision调用,从此以后,向那个流输出带小数点的任何数字时,要么总共保留两个有效数字,要么在小数点之后保留两位——具体由你使用的编译器决定。
precision函数调用只对调用中指定的流生效。如果还有一个名为outStreamTwo的输出流,outStream.precision调用只影响outStream流的输出。当然也可为outStreamTwo调用precision,并指定不同小数位数。
成员函数setf
setf 是 set flag 的缩写,标志(flag)是以二选一方式做一件事情的指令。标志作为setf的实参,该标志就会指示计算机以特定方式将输出写入那个流。
标志 | 含义 | 默认 |
---|---|---|
ios::fixed | 采用定点计数法( fixed-point notation ),如果设置这个标志,就不用e计数法写浮点数(设置该标志会自动取消设置 ios::scientific 标志) | 未设置 |
ios::scientific | 如果设置这个标志,会用e计数法写浮点数(设置该标志会自动取消设置 ios::fixed 标志) 如果未设置 ios::fixed,也未设置 ios::scientific,就由系统决定如何输出每个数字。 | 未设置 |
ios::showpoint | 如果设置这个编制,就始终为浮点数显示小数点和尾随的0.如果没有设置这个标志,而且一个数字在小数点后全是0,那么当这个数字输出时,就可能不会显示小数点和尾随的0。 | 未设置 |
ios::showpos | 如果设置这个标志,正整数之前会输出一个正号 | 未设置 |
ios::right | 如果设置这个标志,同时调用width指定了域宽,输出的下一项会对其指定域的右侧(右对齐)。也就是说,在输出的项之前,会根据需要添加填充空格(设置该标志会自动取消设置 ios::left 标志) | 已设置 |
ios::left | 如果设置这个标志,同时调用width指定了域宽,输出的下一项会对其指定域的左侧(左对齐)。也就是说,在输出的项之前,会根据需要添加填充空格(设置该标志会自动取消设置 ios::right 标志) | 未设置 |
setf 的格式化标志
成员函数width
cout << "Start now";
cout.width(4);
cout << 7 << endl;
// output:
// Start Now 7
width 函数告诉流一个输出项要占多少个字符位置(即域宽)。
本例中,输出项(也就是数字7)只占一个字符位置,而width要求使用4个字符位置,所以其他3个位置用空格填充。如输出所需的字符位置数目超过了在width函数调用中指定的数目,就自动补足缺少的字符位置。总之,输出项始终都会完整输出,不会被截短,无论为width指定的参数是什么。
操纵元
**操纵元(manipulator)**是以非传统方式调用的函数。调用操纵元后,它本身又会调用一个成员函数,操纵元位于插入操作符 << 之后。和传统函数一样,操纵元可以有,也可以没有参数。
要使用setw 或 setprecision 操纵元,必须在程序中包含以下预编译指令 :
#include <iomanip>
using namespace std;
操纵元setw ≈ width,setprecision ≈ precision。使用setprecision操纵元设置小数位置时,和成员函数precision的情况一样,设置会一直生效,直到把它重设为其他数字(通过再次调用setprecision或precision)。
程序示例:
cout << "Start" << setw(4) << 10
<< setw(4) << 20 << setw(6) << 30;
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout << "$" << setprecision(2) << 10.3 << endl
<< "$" << 20.5 << endl;
// output:
// Start 10 20 30
// $10.30
// $20.50
字符I/O
get成员函数
所有数据都作为字符数据输入输出。get函数允许读取输入的一个字符,并把它存储到char类型变量。每个输入流都提供了get成员函数,无论是输入文件流,还是cin流。
以前曾为cin使用提取操作符>>,目的是读取字符输入(或其他任何输入)。以前使用提取操作符>>时,有的工作是自动完成的,比如忽略空白。而无论下个输入字符是空白字符(空格、制表符等)还是换行符,get都会读取它。get函数获取char类型的变量作为参数,调用get时,会读取下一个输入字符,并把实参变量(Char_Variable)设为该字符:
语法 inputStream.get(Char_Variable);
示例 char nextSymbol;
cin.get(nextSymbol);
要用get从文件读取输入,就用输入文件流代替cin流。例如,假定inStream是文件输入流,以下语句从书入围奖读取一个字符并把它放到char变量nextSymbol中:
inStream.get(nextSymbol);
为输入文件流(比如inStream)使用get前,程序必须先调用open函数将流连接到输入文件中。
put成员函数
每个输出流都有名为put的成员函数,它获取一个char类型的参数。调用成员函数put后,它的参数(Char_Expression)的值被输出到输出流。
语法 outputStream.put(Char_Expression);
示例 cout.put(nextSymbol);
cout.put(‘a’);
要用put向文件输出,就用输出文件流代替cout流。例如,假定outStream是文件输出流,则以下代码将字符’Z’输出到与outStream流连接的文件:
outStream.put(‘Z’);
为输出文件流(比如outStream)使用成员函数put之前,程序必须先调用open函数将流连接到输出文件。
putback成员函数
putback是每个输入流都有的成员函数,它获取一个char参数,并将该参数的值放回输入流。该参数可以是能求值为char值的任何表达式。
fin.get(next);
while (next != ' '){
fout.put(next);
fout.get(next);
}
fin.putback(next);
以上代码从与输入流fin连接的文件读取字符,将它们写入与输出流fout连接的另一个文件。代码一直读取字符,直到(但不包括)第一个空格。
注意,执行完这段代码之后,已被读取的空格仍然包含在输入流fin中,因为代码在读取了这个空格之后,又把它放回原来的输入流中。还要注意,putback是将一个字符放回输入流中,而put是将一个字符放到输出流中。被成员函数putback放回输入流的字符不一定是上次读取的字符,它可以是任意字符。putback是将字符放回输入流而不是放回输入文件,原始输入文件的内容不发生任何变化。