大纲
标准 I/O 流的介绍
I/O 流的概念
程序的输入指的是从输入文件将数据传送给程序,程序的输出指的是从程序将数据传送给输出文件。C++ 的输入输出包含以下三个方面的内容:
对系统指定的标准设备的输入和输出
:即从键盘输入数据,输出到显示器屏幕。这种输入输出称为标准的输入输出,简称 标准 I/O
。以外存磁盘文件为对象进行输入和输出
:即从磁盘文件输入数据,数据输出到磁盘文件。以外存文件为对象的输入输出称为文件的输入输出,简称 文件 I/O
。对内存中指定的空间进行输入和输出
:通常指定一个字符数组作为存储空间(实际上可以利用该内存空间存储任何信息)。这种输入和输出称为字符串输入输出,简称 串 I/O
。
I/O 流类库的结构
在 C 语言中,用 printf
和 scanf
进行输入输出,往往不能保证所输入输出的数据是可靠的安全的。在 C++ 的输入输出中,编译系统对数据类型进行严格的检查,凡是类型不正确的数据都不可能通过编译。因此 C++ 的 I/O 操作是类型安全(Type Safe)的。C++ 的 I/O 操作是可扩展的,不仅可以用来输入输出标准类型的数据,也可以用于用户自定义类型的数据。C++ 通过 I/O 类库来实现丰富的 I/O 功能。这样使 C++ 的输人输出明显地优于 C 语言中的 printf
和 scanf
,但是也为之付出了代价,C++ 的 I/O 系统因此变得比较复杂,要掌握许多使用细节。C++ 编译系统提供了用于输入输出的 iostream
类库。iostream
这个单词是由 3 个部分组成的,即 i-o-stream
,意为输入输出流。在 iostream
类库中包含许多用于输入输出的类,如下图所示:
ios
是抽象基类,由它派生出 istream
类和 ostream
类,两个类名中第 1 个字母 i 和 o 分别代表输入(input)和输出(output)。istream
类支持输入操作,ostream
类支持输出操作,iostream
类支持输入输出操作。iostream
类是从 istream
类和 ostream
类通过多重继承而派生的类,其继承层次如下图所示:
iostream
类库中不同的类的声明被放在不同的头文件中,用户在自己的程序中用 #include
命令包含了有关的头文件,这就相当于在本程序中声明了所需要用到的类。可以换 — 种说法:头文件是程序与类库的接口。iostream
类库的接口分别由不同的头文件来实现,常用的头文件如下:
strstream
:用于字符串流 I/Ofstream
:用于实现文件的 I/O 操作iomanip
:在使用格式化 I/O 时,应包含此头文件iostream
:包含了对输入输出流进行操作所需的基本信息stdiostream
:用于混合使用 C 语言和 C++ 的 I/O 机制,例如希望将 C 语言程序转变为 C++ 程序
在 iostream
头文件中定义的类有 ios,istream,ostream,iostream,istream_withassign,ostream_withassign,iostream_withassign
等。在 iostream
头文件中不仅定义了相关的类,还定义了 4 种标准 I/O 对象,如下所示:
<<
和 >>
本来在 C++ 中是被定义为左位移运算符和右位移运算符的,由于在 iostream
头文件中对它们进行了重载,使它们能用作标准类型数据的输入和输出运算符。所以,在使用到它们的程序中必须用 #include <iostream>
命令将其包含到程序中。在 iostream
中只对 <<
和 >>
运算符用于标准类型数据的输入输出进行了重载,但未对用户声明的类型数据的输入输出进行重载。如果用户声明了新的类型,并希望用 <<
和 >>
运算符对其进行输入输出,则需要按照 C++ 的运算符重载规则来做。
标准 I/O 流的使用
标准输入流的简单使用
标准输入流对象 cin
的常用函数如下:
cin.get()
,一次只能读取一个字符cin.get(一个参数)
,读一个字符cin.get(多个参数)
,可以读字符串cin.getline()
,读取整行字符串,包括读取空格字符cin.ignore()
,用于忽略或清除输入缓冲区中的一个或多个字符cin.putback()
,将数据放回缓冲区cin.peek()
,返回值是一个 char
型的字符,即指针指向的当前字符,但它只是观测指针停留在当前的位置并不后移;如果要访问的字符是文件结束符,则函数的返回值是 EOF
或者 -1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include <iostream>
using namespace std;
void input1() { int number; cout << "请输入一个数字: "; cin >> number; cout << "输入的数字是: " << number << endl; }
void input2() { char buf[1024]; cout << "请输入字符串: "; cin >> buf; cout << "输入的字符串: "; cout << buf << endl; }
void input3() { char ch; cout << "请输入字符串: "; while ((ch = cin.get()) != EOF) { cout << ch << " "; } }
void input4() { char a, b, c; cout << "请输入字符串: "; cin.get(a); cin.get(b); cin.get(c); cout << a << b << c; }
void input5() { char buf[256]; cout << "请输入字符串: "; cin.getline(buf, 256); cout << buf << endl; }
void input6() { char buf1[256]; char buf2[256]; cout << "请输入字符串:"; cin >> buf1; cin.ignore(2); cin.getline(buf2, 256); cout << buf1 << endl; cout << buf2 << endl; }
void input7() { char buf1[256]; char buf2[256]; cout << "请输入字符串:"; cin >> buf1; cin.ignore(2); int num = cin.peek(); cout << num << endl; cin.getline(buf2, 256); cout << buf1 << endl; cout << buf2 << endl; }
void input8() { cout << "Please, enter a number or a word: "; char c = std::cin.get();
if ((c >= '0') && (c <= '9')) { int n; cin.putback(c); cin >> n; cout << "You entered a number: " << n << '\n'; } else { char ch; cin.putback(c); cin.get(ch); cout << "You entered a character: " << ch << '\n'; } }
|
标准输出流的简单使用
标准输出流对象 cout
的常用函数如下:
cout.flush()
cout.put()
cout.write()
cout.width()
cout.fill()
cout.setf()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream> #include <iomanip>
using namespace std;
void output1() { cout.put('h').put('e').put('l').put('l').put('o').put('\n'); }
void output2() { char* str = "hello world\n"; cout.write(str, strlen(str)); }
void output3() { cout << "<Start>"; cout.width(30); cout.fill('*'); cout.setf(ios::showbase); cout.setf(ios::internal); cout << hex << 123 << "<End>\n"; }
void output4() { cout << "<Start>" << setw(30) << setfill('*') << setiosflags(ios::showbase) << setiosflags(ios::internal) << hex << 123 << "<End>\n"; }
int main() { output1(); output2(); output3(); output4(); return 0; }
|
程序运行输出的结果如下:
1 2 3 4
| hello hello world <Start>0x**************************7b<End> <Start>0x**************************7b<End>
|
文件 I/O 流的简单使用
以普通的方式读写文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <iostream> #include "fstream"
using namespace std;
void writeFile() { char* fname = "D:/file.txt"; ofstream fout(fname); if (fout) { fout << "Hello World" << endl; fout.flush(); fout.close(); } }
void readFile() { char ch; char* fname = "D:/file.txt"; ifstream fin(fname); if (fin) { while (fin.get(ch)) { cout << ch; } fin.close(); } }
void writeFileApp() { char* fname = "D:/file.txt"; ofstream fout(fname, ios::app); if (fout) { fout << "What" << endl; fout.flush(); fout.close(); } }
int main() { writeFile(); readFile(); writeFileApp(); readFile(); return 0; }
|
程序运行输出的结果如下:
1 2 3
| Hello World Hello World What
|
以二进制的方式读写文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| #include <iostream> #include "fstream"
using namespace std;
class Teacher {
public: Teacher() { age = 33; strcpy(name, ""); }
Teacher(int _age, char* _name) { age = _age; strcpy(name, _name); }
void print() { cout << "age:" << age << ", name:" << name << endl; }
private: int age; char name[32]; };
int main() { char* fname = "D:/file.dat"; ofstream fout(fname, ios::binary); if (!fout) { cout << "打开文件失败" << endl; return 0; }
Teacher t1(23, "Jim"); Teacher t2(26, "Tom"); fout.write((char*)&t1, sizeof(Teacher)); fout.write((char*)&t2, sizeof(Teacher)); fout.flush(); fout.close();
ifstream fin(fname); if (!fin) { cout << "打开文件失败" << endl; return 0; }
Teacher tmp; fin.read((char*)&tmp, sizeof(Teacher)); tmp.print(); fin.read((char*)&tmp, sizeof(Teacher)); tmp.print(); fin.close();
return 0; }
|
程序运行输出的结果如下:
1 2
| age:23, name:Jim age:23, name:Jim
|