本章演示了如何在文本文件中存储和检索数据,并说明了如何避免C++程序中的错误。
![](https://img.haomeiwen.com/i12713060/fcf867ec8c4e5b4f.png)
写文件
写文件的格式可以被指定为人类可读的纯文本格式或机器可读的二进制格式。
标准的C++ <fstream>库提供了处理文件的功能,可以通过在程序开始时添加#include <fstream>指令来实现。
对于每个要打开的文件,首先必须创建文件流对象。这将是"ofstream"(输出文件流)对象,用于向文件写入数据,或"ifstream"(输入文件流)对象,用于从文件读取数据。ofstream对象的使用方式类似于向标准输出写入的cout函数,而ifstream对象的工作方式类似于从标准输入读取的cin函数。
默认情况下ofstream覆盖而没有警告。
#include <fstream>
#include <string>
#include <iostream>
using namespace std ;
int main()
{
string poem = "\n\tI never saw a man who looked" ;
poem.append( "\n\tWith such a wistful eye" ) ;
poem.append( "\n\tUpon that little tent of blue" ) ;
poem.append( "\n\tWhich prisoners call the sky" ) ;
ofstream writer( "poem.txt" ) ;
if( ! writer )
{
cout << "Error opening file for output" << endl ;
return -1 ;
}
writer << poem << endl ;
writer.close() ;
return 0 ;
}
![](https://img.haomeiwen.com/i12713060/e4c3de978ed5198b.png)
追加
创建文件流对象时,名称后可含额外的参数,指定一系列的文件 "模式 "来控制该文件流对象的行为。这些文件模式是ios命名空间的一部分。
![](https://img.haomeiwen.com/i12713060/9bdf8a4721e2c798.png)
使用using namespace std; 的预处理器指令允许省略std命名空间前缀--因此cout指的是std::cout函数。ios命名空间存在于std命名空间中--所以文件模式也可以明确地使用两个命名空间前缀来处理,例如std::ios::out。
用"|"管状字符分隔,可以指定多个模式。当没有明确指定模式时,默认行为是将文件视为文本文件,重写。
最常的模式是ios::app,它不会覆盖原来内容
append.cpp
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string info = "\n\tThe Ballad of Reading Gaol" ;
info.append( "\n\t\t\tOscar Wilde 1898" ) ;
ofstream writer( "poem.txt" , ios::app ) ;
if( ! writer )
{
cout << "Error opening file for output" << endl ;
return -1 ;
}
writer << info << endl ;
writer.close() ;
return 0 ;
}
![](https://img.haomeiwen.com/i12713060/431eb6235baebf3d.png)
读取字符和行
ifstream filestream对象的get()函数,可以用来读取文件。
read.cpp
//#include <string>
#include <fstream>
#include <iostream>
using namespace std ;
int main()
{
char letter ;
int i ;
//string line ;
ifstream reader( "poem.txt" ) ;
if( ! reader )
{
cout << "Error opening input file" << endl ;
return -1 ;
}
else
for( i = 0; ! reader.eof() ; i++ )
{
reader.get( letter ) ;
cout << letter ;
//getline( reader , line ) ;
//cout << line << endl ;
}
reader.close() ;
cout << "Iterations: " << i << endl ;
return 0 ;
}
![](https://img.haomeiwen.com/i12713060/11db7be5f75bef6b.png)
使用getline进行格式化
getline()函数可以选择有第三个参数,以指定停止读取行的分隔符。这可以用来分隔从数据文件中的表格列表中读取的文本。
![](https://img.haomeiwen.com/i12713060/a296bd2d43e3a72e.png)
format.cpp
#include <fstream>
#include <string>
#include <iostream>
using namespace std ;
int main()
{
const int RANGE = 12 ; // Create a size constant.
string tab[ RANGE ] ; // Create a string array.
int i = 0 , j = 0 ; // Create counter variables.
ifstream reader( "records.txt" ) ; // Create input file object.
if( ! reader ) // Always check this.
{
cout << "Error opening input file" << endl ;
return -1 ;
}
while( ! reader.eof() ) // Loop through data...
{
if( (i+1) % 4 == 0 )
getline( reader, tab[ i++ ], '\n' ) ; // If last item on line stop at \n.
else
getline( reader, tab[ i++ ], '\t' ); // Otherwise stop at \t.
}
reader.close() ;
i = 0 ; // Reset the counter.
while( i < RANGE ) // Display each record.
{
cout << endl << "Record Number: " << ++j << endl ;
cout << "Forename: " << tab[ i++ ] << endl ;
cout << "Surname: " << tab[ i++ ] << endl ;
cout << "Department: " << tab[ i++ ] << endl ;
cout << "Telephone: " << tab[ i++ ] << endl ;
}
return 0 ;
}
![](https://img.haomeiwen.com/i12713060/966d85d9735f48f9.png)
网友评论