#edu023. 第 4 节 输入与输出
第 4 节 输入与输出
C++ 提供多种输入、输出方式,接下来进行一一介绍。
cin/cout
是 C++ 概念,是流控制输入输出,需要包含头文件 iostream 。 scanf/printf
和 getchar/putchar
是 C 的标准输入输出函数,需要包含头文件 stdio.h 或 cstdio .
1. 标准输入输出流 cin/cout
cin/cout
是流输入输出函数,需要包含 iostream 头文件,如果需要控制格式,还需要包含 iomanip 头文件。
即:
#include<iostream>
#include<iomanip>
流读取运算符 >>
和 cin
结合在一起使用,可从键盘输入数据。
格式 : cin>>变量;
读入一个值,将值赋给变量。
例如:
int n;
cin>>n;
格式 : cin>>变量1>>变量2 ;
连续读入多个值。
例如:
int a,b,c;
cin>>a>>b>>c; //等价于 cin>>a; cin>>b; cin>>c;
使用 cin 读入整型,遇到空格、换行会停止读入,当同时读入多个值时,用空格将两个整数分开。
流插入运算符 <<
和 cout
结合在一起使用,可以输出数据。
格式 : cout<<表达式 ;
将表达式的值输出。
例如:
int a=5,b=3;
cout<<a+b; //输出8
格式 : cout<<表达式1<<表达式2 ;
输出多个表达式的值。
例如:
int a=5,b=3;
cout<<a<<"+"<<b<<"="<<a+b; //输出5+3=8
双引号 "+" 是字符串,会原样输出。
cout<<'\n';
和 cout<<endl;
都能输出换行符,但cout<<endl
会刷新缓存区降低速度,这种情况下关闭流同步也不能加快输出速度,换行建议都使用 cout<<'\n'
.
2. 格式化控制输入输出函数 scanf/printf
scanf/printf
是 C 的格式化控制输入输出函数,要包含头文件 stdio.h 或 cstdio .
scanf
是格式化输入函数,使用格式如下:
scanf("格式控制符",地址列表)
格式控制符指定了读入的数据类型,地址列表是读入变量的内存地址,利用 &
可以获得变量地址,例如 &a
就是变量 a 的内存地址。例如
int a,b;
scanf("%d%d",&a,&b);
%d
指定了读入类型是整型,第一个 %d
输入的值赋给 , 第二个 %d
输入的值赋给 .
格式控制符是由 % 和字符构成的,不同类型对应不同的格式控制符,常见类型对应的格式控制符如下表:
类型 | 格式控制符 | 说明 |
---|---|---|
int | %d | 整型控制符 ,例如int a; scanf("%d",&a); |
long long | %lld | 长整型控制符,例如 long long a; scanf("%lld",&a); |
float | %f | 单精度浮点数,例如 float x; scanf("%f",&x); |
double | %lf | 双精度浮点数,例如 double x; scanf("%lf",&x); |
long double | %Lf | 长双精度浮点数,例如 long double x; scanf("%Lf",&x); |
char | %c | 单个字符,例如 char ch; scanf("%c",&ch); |
字符数组 | %s | 字符串输入,例如 char ch[21]; scanf("%s",ch); 注意字符数组名就是地址,因此不用取地址 |
printf
是格式化输出函数,使用格式如下
printf("格式控制符",输出列表);
格式控制符由 % 和特定字符构成,指定了输出的类型。不同的类型对应不同的格式控制字符,如 scanf
表格。
双引号中其他普通字符,会原样输出,用于提示或分隔。
输出时,对于 %d、%f、%s 有不同的控制方式:
整型控制:
%d | ||
---|---|---|
参数 | 说明 | 实例 |
%d | 以整型输出,占实际宽度 | int a=123;printf("a=%d",a); //输出 a=123 |
%md | 指定输出宽度占m位,不足m位在前面补空格,超过m以实际宽度输出 | int a=123;printf("a=%5d",a); //输出a= 123 |
%-md | 含义同上,在后面补空格,左对齐 | int a=123;printf("a=%-5d.",a); //输出a=123 . |
%0md | 指定输出宽度占m位,不足m位在前面补0 | int a=123;printf("a=%05d",a); //输出a=00123 |
实数的格式控制:
由于 %f 对应是单精度,我们以 %lf 为例:
%lf | ||
---|---|---|
参数 | 说明 | 实例 |
%lf | 按实数格式输出,整数部分按实际位数输出,默认保留6位小数 | double p=3.14159265358; printf("p=%lf",p); //输出p=3.141593 |
%m.nlf | 总位数m(含小数点),其中有n位小数 | double p=3.14159265358; printf("p=%5.2lf",p); //输出p= 3.14 |
%-m.nlf | 同上,左对齐 | double p=3.14159265358; printf("p=%-5.2lf.",p); //输出p=3.14 . |
3. getchar/putchar
getchar()
用于读入单个字符,来源头文件 <stdio.h> ,它的返回值是读取的字符的 ASCII 码值。如果读取失败或到达文件末尾,getchar()
会返回常量 EOF(End Of File),其实际值为 -1 .
- 通常把输入的字符赋予一个字符变量,构成赋值语句。例如:
char ch;
ch=getchar();
- getchar 函数只能接受单个字符,输入数字也按字符处理。
- 输入多于一个字符时,只接收第一个字符。
- 如果在程序中连续有两个以上getchar()函数,应该一次性输入所需字符,最后再按回车键,否则会把回车作为一个字符传给后面的getchar()函数。
putchar()
函数是字符输出函数,功能是输出单个字符,使用格式:putchar(字符)
, 例如:
char ch='a';
putchar(ch);
getchar/putchar
只能输入输出单个字符,但是由于速度较快,往往配合循环,进行快读,关于快读部分,可以参考文档“输入输出速度比较” 。
4. 输入输出速度比较
在默认情况下,cin/cout
是极为迟缓的读入/输出方式,而 scanf/printf 比 cin/cout
快得多。
当输入输出数据规模达到 ,cin/cout
较慢,就要考虑读写加速。
-
方法一:使用
scanf/printf
头文件包含 , 使用
scanf/printf
进行读写。 -
方法二:关闭流同步
关闭流同步后,
cin/cout
与scanf/printf
速度相当。 在主函数main()
添加关闭流同步代码,解除cin
,cout
绑定。//... int main() { ios::sync_with_stdio(0); //关闭流同步 cin.tie(0); //解除绑定 //... return 0; }
如果搭配上文件读写,主函数核心代码如下:
//... int main() { freopen("输入文件名","r",stdin); freopen("输出文件名","w",stdout); ios::sync_with_stdio(0); cin.tie(0); //... return 0; }
注意: (1)关闭流同步后,不要和
scanf/getchar
C读入方式混用。 (2)也不要使用 endl 换行,使用 “\n” 换行。(3)有文件读写,不能关闭文件。 -
方法三:使用
getchar()/putchar()
进行快读快写可以自定义读写函数,利用 getchar/putchar 进行快读快写。
快读:
int read() { int x = 0, w = 1; char ch = 0; while (ch < '0' || ch > '9') { // ch 不是数字时 if (ch == '-') w = -1; // 判断是否为负 ch = getchar(); // 继续读入 } while (ch >= '0' && ch <= '9') { // ch 是数字时 x = x * 10 + (ch - '0'); // 将新读入的数字「加」在 x 的后面 // x 是 int 类型,char 类型的 ch 和 '0' 会被自动转为其对应的 // ASCII 码,相当于将 ch 转化为对应数字 // 此处也可以使用 (x<<3)+(x<<1) 的写法来代替 x*10 ch = getchar(); // 继续读入 } return x * w; // 数字 * 正负号 = 实际数值 }
读入的时候直接调用函数就可以了,例如读入
num
可写为num=read();
利用
putchar()
进行快写。void write(int x) { if (x < 0) { // 判负 + 输出负号 + 变原数为正数 x = -x; putchar('-'); } if (x > 9) write(x / 10); // 递归,将除最后一位外的其他部分放到递归中输出 putchar(x % 10 + '0'); // 已经输出(递归)完 x 末位前的所有数字,输出末位 }
输出 num 可写为
write(num);