[知识点] 1.4.1 流输入输出

总目录 > 1  语言基础 > 1.4  C++ 语言基础 > 1.4.1  流输入输出

前言

初识 C++ 时,最不明白的概念之一就是所谓的流。其实就是个很普通的比喻。

子目录列表

1、流的概念

2、cin 与 cout

3、cin.get() 与 cin.getline()

 

1.4.1  流输入输出

1、流的概念

在 C++ 中,I/O(Input / Output)输入输出数据是一些从原设备到目标设备的字节序列,称为字节流。字节流通常代表的都是字符。字符序列从原设备连续不断地流向目标设备,最后按先流出先到达的有序方式汇聚到目标设备中,如何河流一般,所以叫

流分为输入流和输出流。输入流(Input Stream, IS)指从输入设备流向内存的字节序列。输出流(Output Stream, OS)指从内存流向输出设备的字节序列。在 C++ 中,标准输入设备通常指键盘,标准输出设备通常指显示器

 

2、cin 与 cout

cin 和 cout 分别为 C++ 中最常用的输入与输出函数,它们被包含于 <iostream> 库中。

① cin 输入

cin 作用是从键盘输入,一般格式为:

cin >> 变量名;

>> 为提取运算符,用于从输入流提取数据,并存储于其后的变量中。在一条 cin 语句中可以输入多个变量,并用 >> 相连,如:

cin >> a >> b;  // 表示输入两个变量 a, b

② cout 输出

cout 作用是输出到屏幕,一般格式为:

cout << 变量名;

<< 为插入运算符,用于将右边变量的 x 的值插入到输出流(屏幕)中。在一条 cout 语句中可以输出多个变量,并用 << 相连,如:

cout << a << ' ' << b;  // 表示输出一个变量 a 和一个 b,中间有一个空格
cout << "Hello, world!";  // 表示输出一个字符串 “Hello, world!”
cout << a << endl; // 表示输出一个变量 a,endl 为换行符

关于换行,'\n' 为 C 风格的换行符,在 cout 中同样适用(所有转义字符均适用);endl 仅适用于 cout,还附带了清空缓冲区的功能。

③ 控制符

不同于 scanf / printf,cin / cout 无需说明变量的数据类型,系统会自动识别,所以也就不需要麻烦的格式说明符了,但为了实现设置浮点数精度和输出域宽等功能,cout 也提供了许多控制数据输入输出格式的函数(操纵函数),它们均在 <iomanip> 库中定义。

> setprecision 设置浮点数精度

一般格式为:cout << setprecision(n) << 变量名;

n 表示有效数字位数。一旦添加了该函数,接下来所有 cout 输出流的浮点数均被指定为该有效数位,除非下次再次使用该函数重新设置。

举例:

cout << setprecision(3) << 23.33 << ' ' << 2333 << ' ' << 2.333;

将输出 “23.3 2333 2.33”。2333 为整型数,不受 setpercision 函数影响。

在 setprecision(n) 前加上 fixed,可以使 n 的意义从有效数位变为小数位数

举例:

cout << fixed << setprecision(3) << 23.33 << ' ' << 2333 << ' ' << 2.333;

将输出 “23.330 2333 2.333”.

> setw 设置域宽

一般格式为:cout << setw(n) << 变量名;

n 表示域宽(即输出数据占用的列数),a 表示要被设置的变量。默认数据按右对齐,若 n 大于数据位数,则数据左侧留空;反之则会自动扩展到所需列数。注意,和 setprecision 不同的是,setw 仅对紧随其后的一个变量有效,即 a。

举例:

cout << setw(8) << 123.4 << setw(7) << 567.8;

将输出 “  123.4  567.8”。123.4 本身占用 5 个字符,所以前面留空 8 - 5 = 3 个字符,567.8 同理。

> setiosflags 各类设置

一般格式为:cout << setiosflags(n) << 变量名;

n 可以为各类预设的常数值,如下:

  setiosflags(ios::fixed) 固定的浮点显示  // 等价于直接加 fixed 
  setiosflags(ios::scientific) 指数表示 
  setiosflags(ios::left) 左对齐 
  setiosflags(ios::right) 右对齐  // 默认为右对齐
  setiosflags(ios::skipws) 忽略前导空白 
  setiosflags(ios::uppercase) 16进制数大写输出 
  setiosflags(ios::lowercase) 16进制小写输出 
  setiosflags(ios::showpoint) 强制显示小数点 
  setiosflags(ios::showpos) 强制显示符号

同 setprecision,一经设置,则接下来所有变量均会遵循该设置,直到使用 resetiosflasgs(n) 函数用于取消该设置 n

> 数制基数

一般格式为 cin / cout << hex / oct / dec << 变量名;

hex, oct, dec 分别表示十六进制、八进制、十进制数

注意,数制基数同样适用于 cin,但再输入时要有特定的格式:十进制无要求;八进制在输入数据前加上 0,十六进制在输入数据前加上 0x。同 setprecision,数制一经设置,接下来所有变量均为该数制。

另外,cin 流输入有一个特点 —— 如果当前接收的数据与当前被存储的变量数据类型不同,C++ 并不会报错,也不会进行转换,而是将多出的部分保存在缓存区,等待下一个变量;或者等待缺失的部分被读入。

 

3、cin.get() 与 cin.getline()

cin 的使用方式并不局限于上述常规方法。cin 包含许多成员函数,下面进行一些介绍。

① cin.get() 单字符读入

一般格式为:cin.get(c),c 存储提取的字符。

使用 get,可以提取输入流中的绝大多数字符,包括空格、Tab 制表符等。和功能类似的 getchar() 函数不同的是,cin.get() 读到换行符时会结束。

(教材上写换行符 '\n' 也会读入,但实测并不会,不知道是什么原因)

c 可以缺省,用于略过当前输入流的字符。

② cin.getline() 字符串读入

一般格式为:

cin.getline(char *c, int n, char = '\n')

其中,char *c 表示保存输入数据的字符数组,n 为要提取的字符个数(实际读取 n - 1 个字符,并在第 n 个位置补充 '\0' 表示结束),char = '\n' 表示提取到换行符时结束读取(缺省时默认为 '\n')。

举例:

cin.getline(c, 10, '0');

表示将提取 9 个字符到 c,如果中间出现 '0',将提前结束提取。

注意,当输入流的字符大于设定值 n 时,cin.getline() 会把余下字符留在输入流中,并关闭输入,此后所有 cin 语句全部失效不再执行。这时调用 cin.clear(),可以恢复为有效,但不会清除输入流中的字符。这时就可以用到 cin.ignore()。

③ cin.ignore() 读入忽略

一般格式为:

cin.ignore(int n = 1, char = EOF);

其中,n 表示忽略掉的字符个数,缺省时默认为 1;char = EOF 表示忽略到 EOF 时结束忽略(缺省时默认为 EOF,EOF 为 End Of File 的缩写,表示资料源无更多的资料可读)

上述 cin.getline() 的输入溢出问题,在使用 cin.clear() 后,可以使用 cin.ignore() 来忽略掉被遗留在输入流的字符。

④ cin.eof() 流结束位

返回当前输入流是否已经结束,一般适用于题目未给出输入量的情况,使用方法为:

while (!cin.eof()) {
    cin >> n >> ...
    ...
}

C 语言风格输入也有作用相同的写法,这里也提一下:

while (scanf("%d", &n) != EOF) {
    ...
}

④ '\n' 遗留问题

cin 读入时不会提取 '\n',也就是说,如果我们接着使用 cin.getline() 或者其他不忽略 '\n' 但又需要忽略的字符提取函数时,就会出现问题,这时有三种方式解决掉这个 '\n':

  > getchar();

  > cin.get();

  > cin.ignore(1);

posted @ 2020-09-01 22:38  jinkun113  阅读(543)  评论(0编辑  收藏  举报