跳转至

Chapter 17 输入、输出和文件

1)c++的输入与输出概论

(1)流和缓冲区

【1】流: ![[Pasted image 20230807131213.png]] ![[Pasted image 20230807131235.png]]

【2】缓冲区: ![[Pasted image 20230807131415.png]] ![[Pasted image 20230807131428.png]]

ps:c++程序常在用户按下回车键时刷新输入缓冲区,常在用户发送换行符时刷新输出缓冲区

(2)管理流和缓冲区的工作

【1】类别:

(1)streambuf类:为缓冲区提供了内存,并提供了用于填充缓冲区、访问缓冲区内容、刷新缓冲区、管理缓冲区内存的类方法 (2)ios_base类:表示流的一般特征,如:是否可以读取、是二进制流还是文本流... (3)ios类:基于ios_base,其中新增了一个指向streambuf对象的指针成员 (4)ostream类:从ios类中派生出来的,提供了输出方法 (5)istream类:从ios类中派生出来的,提供了输入方法 (6)iostream类:继承istream与ostream类

ps:要使用上述工具,必须使用适当的类对象。例如:使用ostream对象(如:cout)来处理输出。创建这样的对象将打开一个流,自动创建缓冲区,并将其与流关联起来,同时使得能够使用类成员函数

【2】默认的传入/传出设备解析:

(1)cin对象对应于标准输入流,默认时这个流被关联到标准输入设备(通常为键盘) (2)cout对象对应于标准输出流,默认时这个流被关联到标准输出设备(通常为显示器) (3)cerr对象对应于标准错误流,可用于显示错误信息。默认时这个流被关联到标准输出设备(通常为显示器)。这个流没有被缓冲,这意味着消息被直接发送给屏幕,而不会等到缓冲区填满或新的换行符 (4)clog对象对应于标准错误流,可用于显示错误信息。默认时这个流被关联到标准输出设备(通常为显示器)。但是这个流被缓冲

【3】重定向: 能够改变标准输入与标准输出 <File_Name:改变了输入流的流入端连接,但是流出端仍然和程序相连 >File_Name:改变了输出流的流出端连接,但是流入端仍然和程序相连

2)使用cout进行输出

(poi)刷新输出缓冲区: 【1】问题引入: ![[Pasted image 20230807134139.png]] ![[Pasted image 20230807134325.png]]

【2】知识导入:

C++
1
2
3
1cout<<flush; 刷新缓冲区

2cout<<endl;刷新缓冲区  插入一个换行符

3)使用cin进行输入

(1)cin>>如何检查输入:

![[Pasted image 20230807141413.png]] ![[Pasted image 20230807141431.png]] ![[Pasted image 20230807141447.png]]

(2)流状态:

[1] cin 或 cout对象包含一个描述流状态(stream state) 的数据成员 [2] 流状态由三个 ios_base 元素组成:eofbit、badbit、failbit(每个元素都是一位,要么是1【设置】,要么是0【清除】)

![[Pasted image 20230807142129.png]]

(3)其他istream类方法:

【1】单字符输入: cin.get(char& ch):读取下一个输入字符[即使该字符是空格/制表符/换行符],将输入字符赋给其参数 cin.get( ):读取下一个输入字符[即使该字符是空格/制表符/换行符],将输入字符转换成整型(int)

cin.get(char& ):返回值是(istream&)——cin形式

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
int ct = 0;
char ch;
cin.get(ch);
while(ch!='\n')
{
    cout << ch;
    ct++;
    cin.get(ch);
}
cout << ct <<endl;

输入
I C++ clearly
输出
I C++ clearly
------------------------------------------------------------------------------------------------------------------------------------
如果使用的是cin >> ch;

1输出结果是IC++clearly
2循环不会终止!(cin>>跳过了换行符因此代码不会把换行符('\n')赋给ch


cin.get( ):返回值是int

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int ct = 0;
char ch;
cin.get();
while(ch!='\n')
{
    cout << ch;
    ct++;
    cin.get();
}
cout << ct <<endl;

输入
I C++ clearly
输出
I C++ clearly

需要注意的是:

C++
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
char c1,c2,c3;
cin.get(c1).get(c2) >> c3;      // valid!
等价于:
1) cin.get(c1)返回成cin
2) 然后cin.get(c2),返回一个cin
3) 最后 cin >> c3
(c1  c2 可以是空格c3不可以)
-----------------------------------------------------------------------------------------------------------------------------------
char c1,c2,c3;
cin.get().get() >> c3;          // not valid!
等价于
1) cin.get() 返回一个int值
2) int.get()  ? ? ?

【2】字符串输入: (1)get (str_name , num , divid_char) cpp istream& get(char*, int, char)

(2)getline (str_name , num , divid_char)

C++
1
 istream& getline(char*, int, char)
参数1:用于放置输入字符串的内存单元地址 参数2:要比str的最大字符数大1(用于结尾的空字符) 参数3:指定用作分界符的字符

ps(二者区别): get():将换行符留在输入流中,这样接下来的输入操作首先看到的是换行符 getline():抽取并丢弃输入流中的换行符