目录
(3)【例7.1】编写程序,从键盘输入a,b,c的值求解一元二次方程。如果a=0或判别式的值<0,输出出错信息
(2)【例7.8】从键盘输入字符串,以文件结束符作为结束标志,逐个输出非空格字符
(1)【例7.11】定义一个有十个元素的整形数组,从键盘输入十个整数,将他们放入数组,同时用插入运算符将他们写入当前目录下的f1.txt文件。
(2)【例7.12】从【例7.11】建立的f1.txt文件中读取10个整数放入数组中,找出并输出最大数和它的下标值
(3)【例7.13】从键盘读入一行字符,把其中的个字母字符存放到磁盘文件f2.txt中。再从f2.txt读入数据,把其中的小写字母改写为大写字母并存入磁盘文件f3.txt。
(3)【例7.15】从【例7.14】产生的文件中读数据并显示到屏幕上
4.【例7.18】在一个字符数组c中存放10个整数,以空格为分隔符,要求将它们放到整形数组中排升序,然后再写入原来的字符数组中。
一、前言
在C++中,输入输出是通过流完成的。C++的输出操作将一个对象的状态转化成一个字符序列,输出到某个地方。输入操作则是从某个地方接收一个字符序列,然后将其转换车一个对象的状态所要求的格式。
把接收存放输出数据的地方叫做目标,把输入数据来自的地方叫做源,输入和输出操作可以看成字符序列在源、目标和对象之间的流动。C++把与输入和输出有关的操作定义为一个类体系,放在一个系统库里,供用户调用。
这个执行输入和输出操作的类体系叫做流类,提供流类实现的系统叫做流类库。
此图是简化的流类库的基本类等级图,而不是直接的继承关系图。其实它们都是模板类,箭头表示的是类等级关系。
这个等级关系在头文件iostream.h中说明。在图中,ios类中一个指针成员指向streambuf类的对象。Streambuf类管理流的缓冲区。由于数据隐蔽和封装的需要,普通用户只使用ios、istream和ostream类提供的公有接口,完成流的提取和插入操作。ios类是istream类和ostream类的虚基类,提供对流的格式化I/O操作和错误处理的成员处理的成员函数。从ios类共有派生istream类和ostream类分别提供对流进行提取和插入操作的成员函数,而iostream类通过组合istream类和ostream类支持对一个流进行双向操作,他并没有提供新成员函数。
iostream中预定义四个流对象,它们分别是cin、cout、cerr、clog。事实上可以将cin视为istream的一个对象,而cout视为ostream的一个对象。流是一个抽象的概念,当实际进行I/O操作时,必须将流和一个具体的物理设备连接起来。
C++的流类库预定义的四个流所连接的设备如表所示:
与iostream类库有关的头文件:
iostream类库中不同的类的声明被放在不同的头文件中,用户在程序中用#include命令包含所需的头文件就相当于在程序中声明了所需的类。
iostream 输入输出流操作
fstream 管理文件的I/O操作
strstream 字符流的I/O操作
stdiostream 混合使用C和C++
iomanip 使用格式化I/O操作
在iostream头文件中重载了>>和<<运算符。用于标准类型数据的输入和输出。
二、标准输出流
1.流对象
标准输出流是流向标准输出设备的数据。
ostream类定义了cout、cerr和clog三个流对象。
(1)cout流对象
cout流在内存开辟一个缓冲区存放流中的数据,当遇到endl时,立即输出流中的所有数据,然后插入一个换行符并清空缓冲区。
(2)cerr流对象
cerr流对象是标准出错流。它向标准出错设备输出有关出错的信息。
(3)【例7.1】编写程序,从键盘输入a,b,c的值求解一元二次方程。如果a=0或判别式的值<0,输出出错信息
-
NS流程图
-
代码
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
float a, b, c, disc;
cout << "请输入 a,b,c:";
cin >> a >> b >> c;
if (a == 0)
cerr << "a 等于0,错误!" << endl;
else if ((disc = b * b - 4 * a * c) < 0)
cerr << "判别式b*b-4*a*c<0" << endl;
else
{
cout << "x1=" << (-b + sqrt(disc)) / (2 * a) << endl;
cout << "x2=" << (-b - sqrt(disc)) / (2 * a) << endl;
}
return 0;
}
-
结果
(4)clog流对象
clog流对象也是标准出错流,它与cerr的区别是,cerr不经过缓冲区直接向显示器输出出错信息,clog把出错信息存放在缓冲区,当缓冲区满或遇到endl时向显示器输出出错的信息。
2.格式输出
在输出数据时,如不指定格式,则采用系统给定的默认格式。可以通过控制符或流的成员函数设置输出格式。
(1)用控制符设置输出格式
下表列出了输出格式的控制符。这些控制符在头文件iomanip中定义。
(2)【例7.2】用控制符控制输出格式
- 代码
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int a;
cout << "input a:";
cin >> a;
cout << "dec:" << dec << a << endl;
cout << "hex:" << hex << a << endl;
cout << "oct:" << setbase(8) << a << endl;
char *pt = "China";
cout << setw(10) << pt << endl;
cout << setfill('*') << setw(10) << pt << endl;
double pi = 22.0 / 7.0;
cout << setiosflags(ios::scientific) << setprecision(8) ;
cout << "pi=" << pi << endl;
cout << "pi=" << setprecision(4) << pi << endl;
cout << "pi=" << setiosflags(ios::fixed) << pi << endl;
return 0;
}
- 结果
(3)用流对象的成员函数控制输出格式
用于控制输出格式的常用成员函数如下。
流成员函数setf和控制符setiosflags括号中参数是格式标志,在类ios中定义它是枚举值。所以在引用这些格式标志时要以ios::开始,格式标志列于表7.5。
(4)用流控制成员函数输出数据
#include <iostream>
using namespace std;
int main()
{
int a = 21;
cout.setf(ios::showbase);
cout << "dec:" << a << endl;
cout.unsetf(ios::dec);
cout.setf(ios::hex);
cout << "hex:" << a << endl;
cout.unsetf(ios::hex);
cout.setf(ios::oct);
cout << "oct:" << a << endl;
char *pt = "China";
cout.width(10);
cout << pt << endl;
cout.width(10);
cout.fill('*');
cout << pt << endl;
double pi = 22.0 / 7.0;
cout.setf(ios::scientific);
cout << "pi=";
cout.width(14);
cout << pi << endl;
cout.unsetf(ios::scientific);
cout.setf(ios::fixed);
cout.width(12);
cout.setf(ios::showpos);
cout.setf(ios::internal);
cout.precision(6);
cout << pi << endl;
return 0;
}
前面的【例7.2】和【例7.3】分别用控制符和流成员函数设置输出流中的数据基数,虽然它们的功能相似,但是还是有区别的:
- 用控制符设置输出流的数据基数后,这个设置会一直保留到下一次的设置
- 用成员函数srtf()设置的格式,必须用函数unsetf()终止后才能重新设置,并且函数setf()设置的基数仅仅在本次输出流中生效,之后无论是否用函数unsetf()终止,下次输出流数据又以默认的十进制基数显示
3.用流成员函数put输出字符
(1)介绍
格式:
cout.put(字符/数字)[.put(…) ……]
如果是字符,直接输出该字符;如果是数字,可以用八进制、十进制或十六进制表示整数,用该数字对256取模,输出对应的ASCII码字符。
(2)【例7.4】按相反的顺序输出“BASIC”
#include <iostream>
using namespace std;
int main()
{
char *a = "BASIC";
for (int i = 4; i >= 0; i--)
cout.put(*(a + i));
cout.put('\n');
return 0;
}
三、标准输入流
1.cin流
cin是istream类的对象,从标准输入设备读取数据。利用提取运算符>>在流中提取数据时通常跳过流中的空格、tab键、换行符等字符。只有输入回车键时输入的数据才进入键盘缓冲区,形成输入流,提取运算符才能从其中提取数据。
当遇到无效字符(与变量数据类型不一致)或文件结束符时,输入流cin就处于出错状态,此时对cin流的所有操作都被终止。当输入流出错时,cin的值是false,所以可以根据cin的值判断流对象是否处于正常状态。
2.【例7.5】测试cin的值,判断流对象的状态
#include <iostream>
using namespace std;
int main()
{
float grade;
cout << "enter grade:";
while (cin >> grade)
{
if (grade >= 85)
cout << grade << " GOOD!" << endl;
if (grade < 60)
cout << grade << " fail!" << endl;
cout << "enter grade:";
}
cout << "The end." << endl;
return 0;
}
3.输入字符的流成员函数
(1)用get函数读入一个字符
格式:cin.get()
函数的类型是字符,函数的功能是从输入流中提去一个字符作为函数值返回。如在流中遇到文件结束符EOF时,返回-1。
(2)【例7.6】用get函数读入字符
#include <iostream>
using namespace s