第十七章 文件输入输出
本章内容
(1) C++角度的输入和输出
(2) iostream 类系列
(3) 重定向
(4) ostream 类方法
(5) 格式化输出
(6) istream 类方法
(7) 流状态
(8) 文件 i/o
(9) 使用 ifstream 类从文件输入
(10) 使用 ofstream 类输出到文件
(11) 使用 fstream 类从文件输入和输出
(12) 命令行处理
(13) 二进制文件
(14) 随机文件访问
(15) 内容格式化
17.1 C++输入和输出概述
1. C++中可使用的输入输出
(1) stdio.h 文件中声明的 C 函数系列,也可以在 C++程序中使用(较新的实现使用头文件
cstdio 来支持这些函数)
(2) C++实现的标准类库,iostream 头文件和 fstream 头文件.
2. C++程序通常在用户按下回车键后刷新输入缓冲区
3. C++一些输入输出类的介绍
(1) streambuf 类为缓冲区提供了内存,并提供了用于填充缓冲区,访问缓冲区内容,刷新
缓冲区和管理缓冲区内存的类方法
(2) ios_base 类表示流的一般特征,如是否可读取,是二进制流还是文本流等;
(3) ios 类基于 ios_base 类,其中包括了一个指向 streambuf 类的指针成员;
(4) ostream 类是从 ios 类继承来的,提供了输出方法(例如,cout);
(5) istream 类也是从 ios 类继承来的,提供了输入方法(例如,cin);
(6) iostream 类是基于 ostream 类和 istream 类的,因此继承了输入和输出方法.
4. 重定义 I/O
ISO/ANSI 标准 C++98 对 I/O 作了两方面的修订.
(1)从 ostream.h 到 ostream 的变化,用 ostream 将类放到 std 名称空间中.
(2)为了国际化,在 8 位 char 类型的基础上增加了 wchar_t 字符类型;C++11 还增加了
char16_t 和 char32_t,每种类型都有自己的 I/O 工具.例如 wistream 和 wostream.
17.2 使用 cout 进行输出1. 重载的<<运算符
<< 运算符本为左移运算符,C++将其重载为插入运算符;对于每一种数据类型,ostream 类
都提供了 operator<<()函数的定义.
2. 其它 ostream 方法
除了 operator<<()函数外,ostream 类还提供了 put()方法和 write()方法,前者用于显示字符,
后者用于显示字符串.
调用方法:
cout.put(‘W’);
// display the W charactor
也可以用于拼接输出:
cout.put(‘I’).put(‘t’);
// displaying It with two put() calls
write()方法显示整个字符串,其模板原型如下:
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
3. 刷新输出缓冲区
flush(cout);或 cout << flush
4. 用 cout 进行格式化
(1) 修改显示时使用的计数系统.要控制整数以十进制,十六进制还是八进制显示,可以使
用 dec,hex 和 oct 控制符.
(2) 调整字段宽度.
int width();
int width(int i);
实例:
(3) 填充字符.
默认情况下,cout 用空格填充字段中未被使用的部分,可以使用 fill()成员函数来改变填充
字符,例如,
cout.fill(‘*’);
(4) 设置浮点数的显示精度
浮点数精度的含义取决于输出模式.在默认模式下,它指的是显示的总位数.在定点模式
和科学模式下,精度指的是小数点后面的位数.C++的默认精度为 6 位(但末尾的 0 将不显示).
可以使用 precision()成员函数选择其它值.
例如:
Cout.precision(2);
与 width()方法不同,新的精度设置一直有效,直到被重新设置.
(5) 打印末位的 0 和小数点
对于有些输出,打印末位的 0 可能更为美观.在这里可以使用基类 ios_base 中提供的 setf()
方法.
setf() 函数有两个原型.第一个为:
fmtflags setf(fmtflags);
其中,fmtflags 是 bitmask 类型的 typedef 名,用于存储格式标记.该名称是在 ios_base 类中
定义的.
常用格式常量,如下表所示:
常量 含义
ios_base::boolalpha 输入和输出 bool 值,可以为 true 或 false
ios_base::showbase 对于输出,使用 C++基数前缀(0,0x)
ios_base::showpoint 显示末尾的小数点
ios_base::uppercase 对于 16 进制输出,使用大写字母,E 表示方法
ios_base::showpos 在正数前面加上+
调用方法:
cout.setf(ios_base::showpoint);
第二个原型接收两个参数,并返回以前的设置:
fmtflags setf(fmtflags, fmtflags);
第二个参数 第一个参数 含义
ios_base::basefield ios_base::dec 使用基数 10
ios_base::oct 使用基数 8
ios_base::hex 使用基数 16
ios_base::fixed 使用定点计数法
ios_base::floatfieldios_base::adjustfield
ios_base::scientific 使用科学计数法
ios_base::left 使用左对齐
ios_base::right 使用右对齐
ios_base::internal 符号或基数前缀左对齐,值右
对齐
实例如下:
(6) 标准控制符
使用 setf()不是进行格式化的,对用户最为友好的方法,C++提供了多个控制符,能够调用
setf(),并自动提供正确的参数.与前面的 hex,dec 和 oct 的使用方法相同.
(7) 头文件 iomanip
该头文件提供一些其它的控制符.
17.3 使用 cin 进行输入
典型的运算符函数的原型如下:
istream & operator>>(int &);
本章内容
(1) C++角度的输入和输出
(2) iostream 类系列
(3) 重定向
(4) ostream 类方法
(5) 格式化输出
(6) istream 类方法
(7) 流状态
(8) 文件 i/o
(9) 使用 ifstream 类从文件输入
(10) 使用 ofstream 类输出到文件
(11) 使用 fstream 类从文件输入和输出
(12) 命令行处理
(13) 二进制文件
(14) 随机文件访问
(15) 内容格式化
17.1 C++输入和输出概述
1. C++中可使用的输入输出
(1) stdio.h 文件中声明的 C 函数系列,也可以在 C++程序中使用(较新的实现使用头文件
cstdio 来支持这些函数)
(2) C++实现的标准类库,iostream 头文件和 fstream 头文件.
2. C++程序通常在用户按下回车键后刷新输入缓冲区
3. C++一些输入输出类的介绍
(1) streambuf 类为缓冲区提供了内存,并提供了用于填充缓冲区,访问缓冲区内容,刷新
缓冲区和管理缓冲区内存的类方法
(2) ios_base 类表示流的一般特征,如是否可读取,是二进制流还是文本流等;
(3) ios 类基于 ios_base 类,其中包括了一个指向 streambuf 类的指针成员;
(4) ostream 类是从 ios 类继承来的,提供了输出方法(例如,cout);
(5) istream 类也是从 ios 类继承来的,提供了输入方法(例如,cin);
(6) iostream 类是基于 ostream 类和 istream 类的,因此继承了输入和输出方法.
4. 重定义 I/O
ISO/ANSI 标准 C++98 对 I/O 作了两方面的修订.
(1)从 ostream.h 到 ostream 的变化,用 ostream 将类放到 std 名称空间中.
(2)为了国际化,在 8 位 char 类型的基础上增加了 wchar_t 字符类型;C++11 还增加了
char16_t 和 char32_t,每种类型都有自己的 I/O 工具.例如 wistream 和 wostream.
17.2 使用 cout 进行输出1. 重载的<<运算符
<< 运算符本为左移运算符,C++将其重载为插入运算符;对于每一种数据类型,ostream 类
都提供了 operator<<()函数的定义.
2. 其它 ostream 方法
除了 operator<<()函数外,ostream 类还提供了 put()方法和 write()方法,前者用于显示字符,
后者用于显示字符串.
调用方法:
cout.put(‘W’);
// display the W charactor
也可以用于拼接输出:
cout.put(‘I’).put(‘t’);
// displaying It with two put() calls
write()方法显示整个字符串,其模板原型如下:
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
3. 刷新输出缓冲区
flush(cout);或 cout << flush
4. 用 cout 进行格式化
(1) 修改显示时使用的计数系统.要控制整数以十进制,十六进制还是八进制显示,可以使
用 dec,hex 和 oct 控制符.
(2) 调整字段宽度.
int width();
int width(int i);
实例:
1 // width.cpp--using the width method
2
3 #include <iostream>
4
5 int main()
6 {
7 using std::cout;
8 int w = cout.width(30); //返回值是上一次的默认字宽
9 cout << "default field width = " << w << ":\n";
10 cout.width(5);
11 cout << "N" << ':';
12 cout.width(8);
13 cout << "N * N" << ":\n";
14
15 for (long i=1;i<=100;i*=10)
16 {
17 cout.width(5);
18 cout << i << ':';
19 cout.width(8);
20 cout << i * i << ":\n";
21 }
22 return 0;
23 }
(3) 填充字符.
默认情况下,cout 用空格填充字段中未被使用的部分,可以使用 fill()成员函数来改变填充
字符,例如,
cout.fill(‘*’);
(4) 设置浮点数的显示精度
浮点数精度的含义取决于输出模式.在默认模式下,它指的是显示的总位数.在定点模式
和科学模式下,精度指的是小数点后面的位数.C++的默认精度为 6 位(但末尾的 0 将不显示).
可以使用 precision()成员函数选择其它值.
例如:
Cout.precision(2);
与 width()方法不同,新的精度设置一直有效,直到被重新设置.
(5) 打印末位的 0 和小数点
对于有些输出,打印末位的 0 可能更为美观.在这里可以使用基类 ios_base 中提供的 setf()
方法.
setf() 函数有两个原型.第一个为:
fmtflags setf(fmtflags);
其中,fmtflags 是 bitmask 类型的 typedef 名,用于存储格式标记.该名称是在 ios_base 类中
定义的.
常用格式常量,如下表所示:
常量 含义
ios_base::boolalpha 输入和输出 bool 值,可以为 true 或 false
ios_base::showbase 对于输出,使用 C++基数前缀(0,0x)
ios_base::showpoint 显示末尾的小数点
ios_base::uppercase 对于 16 进制输出,使用大写字母,E 表示方法
ios_base::showpos 在正数前面加上+
调用方法:
cout.setf(ios_base::showpoint);
第二个原型接收两个参数,并返回以前的设置:
fmtflags setf(fmtflags, fmtflags);
第二个参数 第一个参数 含义
ios_base::basefield ios_base::dec 使用基数 10
ios_base::oct 使用基数 8
ios_base::hex 使用基数 16
ios_base::fixed 使用定点计数法
ios_base::floatfieldios_base::adjustfield
ios_base::scientific 使用科学计数法
ios_base::left 使用左对齐
ios_base::right 使用右对齐
ios_base::internal 符号或基数前缀左对齐,值右
对齐
实例如下:
1 // setf2.cpp -- using setf() with 2 arguments to control formatting
2
3 #include <iostream>
4 #include <cmath>
5
6 int main()
7 {
8 using namespace std;
9 //use left justification, show the plus sign,show trailing
10 //zeros, with a precision of 3
11 cout.setf(ios_base::left,ios_base::adjustfield);
12 cout.setf(ios_base::showpos);
13 cout.setf(ios_base::showpoint);
14 cout.precision(3);
15 //use e-notation and save old format setting
16 ios_base::fmtflags old = cout.setf(ios_base::scientific, ios_base::float field);
17 cout << "Left Justification:\n";
18 long n;
19 for (n=1;n<=41;n+=10)
20 {
21 cout.width(4);
22 cout << n << "|";
23 cout.width(12);
24 cout << sqrt(double(n)) << "|\n";
25 }
26
27 // change to internal justification
28 cout.setf(ios_base::internal,ios_base::adjustfield);
29 //restore default floating-point display style
30 cout.setf(old,ios_base::floatfield);
31
32 cout << "Internal Justification:\n";
33 for (n=1;n<=41;n+=10)
34 {
35 cout.width(4);
36 cout << n << "|";
37 cout.width(12);
38 cout << sqrt(double(n)) << "|\n";
39 }
40
41 // use right justification,fixed notation
42 cout.setf(ios_base::right,ios_base::adjustfield);
43 cout.setf(ios_base::fixed,ios_base::floatfield);
44 cout << "Right Justification:\n";
45
46
47 for (n=1;n<=41;n+=10)
48 {
49 cout.width(4);
50 cout << n << "|";
51 cout.width(12);
52 cout << sqrt(double(n)) << "|\n";
53 }
54
55 return 0;
56 }
(6) 标准控制符
使用 setf()不是进行格式化的,对用户最为友好的方法,C++提供了多个控制符,能够调用
setf(),并自动提供正确的参数.与前面的 hex,dec 和 oct 的使用方法相同.
(7) 头文件 iomanip
该头文件提供一些其它的控制符.
17.3 使用 cin 进行输入
典型的运算符函数的原型如下:
istream & operator>>(int &);