流对象与文件操作步骤为:
(1)程序建立一个流对象
(2)指定这个流对象与某个文件对象建立连接
(3)程序操作流对象
(4)流对象通过文件系统对所连接的文件对象产生作用
(5)关闭操作
一、标准I/O对象
cin:标准输入。istream类的对象
cout:标准输出。ostream类的对象
cerr :标准错误输出。ostream类的对象
clog:带缓冲的标准出错信息输出。ostream类的对象
以上四个对象包含在iostream标准头文件中。
1、输入输出机制
C++流类提供了许多控制输入输出的成员函数,通过.或->加以调用。
例如:get()、getline()函数。
虽然利用成员函数能实现输入、输出,但非常不方便,为此C++中通过重载>>和<<运算符来实现数据的输入输出,同时为了便于对输入和输出的控制,又提供了许多可与>>和<<配合使用的特殊函数,称为操作符。
例如:endl和setw就是操作符。
2、输入输出函数
部分常用流对象的成员函数有:
(1)precision( ) 设置显示小数精度,用于cout
(2)width( ) 设置域宽,用于cout
(3)flags( ) 设置基数和填充字符,用于cout
(4)put( ) 输出一个字符,用于cout
(5)write( ) 输出一个字符串,用于cout
(6)get( ) 读取一个字符,用于cin
(7)getline( ) 读取一行字符,用于cin
(8)read( ) 读取一个字符串,用于cin;
//eg11-1:流类成员函数应用
#include <iostream>
using namespace std;
int main()
{
char letter;
while (1)
{
letter = cin.get(); //读取一个字符
letter = toupper(letter);//将小写字母转成大写。
if (letter == 'Y')
{
cout << endl << "OK!" << endl;
break;
}
cout << letter;
}
system("pause");
return 0;
}
//eg11-2:将英文字母及对应的ASCII码输出到屏幕上
#include <iostream>
using namespace std;
int main()
{
for (char ch = 'a'; ch <= 'z'; ch++)
{
int i = ch;
cout.put(ch); //put( ) 输出一个字符
cout.width(6); //width( ) 设置域宽
cout << i << endl;
}
system("pause");
return 0;
}
//eg11-3:使用流类成员函数进行输入输出格式控制
#include <iostream>
using namespace std;
int main()
{
int i;
double x, y;
i = 100;
x = 23.14159;
y = 23.575;
cout << "Default width is:" << cout.width() << endl; //设置域宽
cout << "Default fill is:" << cout.fill() << endl;
cout << "Default priecision is:" << cout.precision() << endl; //precision( ) 设置显示小数精度
cout << i << " " << x << " " << y << endl;
cout.width(10);
cout << i << " " << x << " " << y << endl;
cout.precision(4);
cout << i << " " << x << " " << y << endl;
cout.fill('*');
cout.width(10);
cout << i << " " << x << " " << y << endl;
system("pause");
return 0;
}
结果说明:
在默认情况下:
(1)width()的取值为“0”,表示无域宽,数据按自身的宽度输出;
(2)fill()取值为空格;
(3)pricision()取值为6,即输出时保留6位有效数字,如:23.14159输出时结果为23.1416,保留6位有效数字。
当用width()设置了域宽后,只对紧跟它的第一个输出有影响,之后自动置为0。
而设置fill()和pricision()后,一直有效,除非被重置。
3、常用格式操纵符
需要包含头文件
(1)dec控制按十进制输出,等同于成员函数flags(10);
(2)hex控制按十六进制输出,等同于成员函数flag(16);
(3)oct控制按八进制输出,等同于成员函数flags(8);
(4)setfill(c ) 设置填充字符,等同于成员函数fill(c);
(5)setw(n) 设置域宽,等同于成员函数width(n);
(6)setprecision(n) 设置显示小数精度,等同于成员函数precision(n) 。
二、文件的输入/输出
1、文件流类
文件流是I/O中非常重要的一个内容,它的输入是指从磁盘文件流向内存,它的输出是指从内存流向磁盘。C++中提供了三个文件流类:ofstream,ifstream,fstream,定义在fstream头文件中。其中fstream是ofstream和ifstream多重继承的子类。各文件流类的功能如下:
(1)ofstream:输出流类,用于向文件中写入内容。
(2)ifstream:输入流类,用于从文件中读出内容。
(3)fstream:输入输出流类,用于既要读又要写的文件操作。
2、文件的打开和关闭
文件操作总是包含3个步骤: 打开文件→读/写文件→关闭文件。
(1)打开文件
包括:
建立文件流对象
与外部文件关联
指定文件的打开方式
方法一:先建立流对象,然后调用函数open连接外部文件。
流类 对象名
对象名.open(文件名,方式);
1) 打开一个已有文件datafile.dat,准备读:
ifstream infile; //建立输入文件流对象
infile.open(“datafile.dat”,ios::in); //连接文件,指定打开方式
2)打开(创建)一个文件newfile.dat,准备写:
ofstream outfile; //建立输出文件流对象
outfile.open(“d:\newfile.dat”,ios::out); //连接文件,指定打开方式
方法二:调用流类带参数的构造函数,建立流对象的同时连接外部文件。
流类 对象名(文件名,方式);
ifstream infile(“datafile.dat”,ios::in);
ofstream outfile(“d:\newfile.dat”,ios::out);
fstream rwfile(“myfile.dat”,ios::in|ios::out); //以读写方式打开文件,可以用“|”连接两个表示打开方式的标识常量
说明:
流类是C++流类库定义的文件流类,为ifstream、ofstream或fstream。
“对象名”是用户定义标识符。
“文件名”是用字符串表示外部文件的名字,可以是已经赋值的串变量或者是用双引号括起来的串常量,要求使用文件全名。如果文件不在当前目录,需要写出路径。
“方式”是ios定义的标识常量。见下表。
标识常量 含义
ios::in 读方式打开文件
ios::out 写方式打开文件
ios::ate 打开文件时,文件指针指向文件末尾
ios::app 追加方式,向文件输出的内容追加到文件尾部
ios::trunc 删除文件现有内容(默认)
ios::nocreate 如果文件不存在,则打开操作失败
ios::noreplace 如果文件存在,则打开操作失败
ios::binary 二进制方式打开,默认为文本方式
(2)关闭文件
当一个文件操作完毕后,应及时关闭。
关闭文件操作包括
1)把缓冲区数据完整地写入文件;
2)添加文件结束标志;
3)切断流对象和外部文件的连接。
关闭文件使用fstream的成员函数close()。
ifstream infile;
infile.open(“file1.txt”,ios::in); //读文件
infile.close(); //关闭file.txt
infile.open(“file2.txt”,ios::in); //重用流对象
3、文件的读写
(1)文本文件
文本文件用文本文件流进行读/写。文本文件是顺序存取文件。文本文件用默认方式打开。
//例11-4:写文本文件
#include <iostream>
#include <fstream>
using namespace std;
int main(){
char fileName[30], name[30];
int number, score;
ofstream outfile; //建立输出文件流对象
cout << "Please input the name of students file:" << endl;
cin >> fileName; //输入文件名
outfile.open(fileName, ios::out); //连接文件,指定打开方式
if (!outfile){ //如果打开文件失败,outfile返回0值
cerr << "File could not be open." << endl;
abort();
}
outfile << "This is a file of students\n" << endl;
cout << "Input the number,name,and score:(Enter Ctrl-Z to end input)\n";
cout << "?";
while (cin >> number >> name >> score){
outfile << number << ' ' << name << ' ' << score << '\n'; //向流插入数据
cout << "?";
}
outfile.close();
system("pause");
return 0;
}
//例11-5:读文本文件
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char name[30], s[80];
int number, score;
int n = 0, max, min, total = 0;
double ave;
ifstream infile("student.txt", ios::in);
if (!infile)
{
cerr << "File could not be open." << endl;
abort();
}
infile.getline(s, 80); //略去标题行
while (infile >> number >> name >> score) //提取并测试
{
cout << number << '\t' << name << '\t' << score << endl;
if (n == 0){ max = min = score; }
else
{
if (score>max) max = score;
if (score<min) min = score;
}
total += score;
n++;
}
ave = double(total) / n;
cout << "maximal is:" << max << endl
<< "minimal is:" << min << endl
<< "average is:" << ave << endl;
infile.close();
system("pause");
return 0;
}
//例11-6:文件浏览
#include <iostream>
#include <fstream>
using namespace std;
void browseFile(char * fileName, int delLine)
{
ifstream inf(fileName, ios::in);
char s[80];
for (int i = 1; i <= delLine; i++) //读出开头delLine行不显示
inf.getline(s, 80);
while (!inf.eof())
{
inf.getline(s, 80); //按行读出文件
cout << s << endl; //按行显示
}
inf.close();
}
int main()
{
browseFile("student.txt", 2);
system("pause");
return 0;
}
//例11-7:向文件添加记录
#include <iostream>
#include <fstream>
using namespace std;
int Append(char *fileName)
{
char name[30], ch;
int number, score;
ofstream outfile(fileName, ios::app);
if (!outfile)
{
cerr << "File could not be open." << endl;
return 0;
}
cout << "Do you want append record to " << fileName << "?(Y or N)\n";
cin >> ch;
while (ch == 'Y' || ch == 'y')
{
cin >> number >> name >> score;
outfile << number << ' ' << name << ' ' << score << '\n'; //追加一个记录
cout << "Do you want append record to " << fileName << "?(Y or N)\n";
cout << "?(Y or N)";
cin >> ch;
if (ch == 'N' || ch == 'n')
cout << "Close file.\n";
}
outfile.close();
return 1;
}
int main()
{
Append("c:\\datafiles\\student.txt");
return 0;
}
//eg11-8:复制文本文件
#include <iostream>
#include <fstream>
using namespace std;
int copyFile(char *destFile, char *srcFile){
char ch;
ifstream inFile(srcFile, ios::in);
ofstream outFile(destFile, ios::out);
if (!srcFile)
{
cerr << srcFile << ":File could not be open." << endl;
return 0;
}
while (inFile.get(ch)) //全部字符复制
outFile.put(ch);
inFile.close();
outFile.close();
cout << "finish!" << endl;
return 1;
}
int main(){
copyFile("c:\\datafiles\\new_student.txt", "c:\\datafiles\\student.txt");
return 0;
}