第1关:重要的事情说三遍
任务描述
本关任务:程序接受一个输入字符,然后将该字符输出三遍,再输出一个!
。
相关知识
本关的“小目标”是帮助大家掌握 C 和 C++ 程序中字符的基本输入输出开发技能。
标准输入输出函数库 stdio.h
C 和 C++ 提供了一个标准输入输出函数库stdio.h
。在程序中包含该函数库后,就可以使用其中的标准函数进行输入输出操作了。在程序中表示如下:
// 包含标准输入输出函数库
#include <stdio.h>
字符的输入输出函数
在 C 语言中,输入输出函数有着相当重要的地位,它是我们的程序与用户交互的唯一途径。
标准输入输出函数库提供的函数总体上可分为格式化输入输出函数、单个字符输入输出函数和字符串输入输出函数。下面我们要学习的是单个字符的输入输出函数。
输入函数
字符的输入函数为 getchar,其函数原型为:
int getchar(void);
函数 getchar 没有参数(后面的括号中为空或者 void ),它从标准输入设备(键盘)读入一个字符,并将该字符以整数( int )形式返回。
返回的字符要用于输出,所以不能丢弃。我们需要申明一个变量来存储该字符,申明的变量在内存中会有对应的存储空间。使用变量存储输入的字符的语句为:
// 声明变量 x 存储输入的字符
char x = getchar();
输出函数
字符的输出函数为 putchar,其函数原型为:
int putchar(int c);
函数 putchar 用于向标准输出设备(显示器屏幕)输出一个字符,它的参数 c 是要输出的字符变量或常量。
字符常量是用单引号括起来的一个字符,如'A'
。例如:
char x='A';
putchar(x); // 输出变量 x 中存储的字符
putchar('A'); // 输出字符常量'A'
编程要求
在右侧编辑器中的Begin-End
之间补充代码,程序接收一个输入字符(字符将由平台给出,你只需获取即可),然后将该字符输出三遍并以!
结束。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:A
预期输出:AAA!
测试输入:1
预期输出:111!
开始你的任务吧,祝你成功!
不要瞧不起你手头上所做的每一件琐碎小事,把它们干漂亮了,才能成就将来的大事。
// 包含标准输入输出函数库
#include <stdio.h>
// 定义main函数
int main()
{
// 请在下面编写将字符输出三遍的程序代码
/********** Begin *********/
char h;
h=getchar();
putchar(h);
putchar(h);
putchar(h);
putchar('!');
/********** End **********/
return 0;
}
第2关:整数四则运算表达式的输出格式控制
任务描述
本关任务:用户输入两个四位数以内的整数,请你对两个整数进行四则运算(为保证除法能正确计算,输入的第二个整数不能为0),要求输出的四则运算表达式是完整对齐的。
例如,给定输入1256和20,其符合上述对齐要求的四则运算的输出格式应该如下所示(为了让空格显示的更直观,这里暂用下划线_
表示空格):
_1256 + 20___ = _____1276
_1256 - 20___ = _____1236
_1256 * 20___ = ____25120
_1256 / 20___ = _______62
相关知识
程序的输出格式对用户体验影响很大,用户往往因为输出格式不美观便抱怨软件设计的不好。
那么,如何对程序的输出格式进行控制呢?接下来我们介绍一下格式化输入输出,格式化输入输出可以用函数库stdio.h
中的 scanf 和 printf 两个函数来实现。
scanf 函数
scanf 函数按照一定的格式从键盘输入数据。函数形式为:
scanf (<格式控制串> , <参数列表>) ;
-
<格式控制串> 是一个字符串,说明了输入数据要遵循的格式;
-
<参数列表> 是存放输入数据地址的列表,有多个输入数据时,参数之间用
,
分隔。如果要把输入的数据写入一个变量,参数列表中需要使用变量的地址。获取变量地址的方法为:&变量名
,其中&
是地址运算符,其运算结果是后面的变量的地址。
例如从命令行读入一个整数、一个浮点数、一个整数,分别赋值给 num1、num2 和 num3。如下代码:
scanf(″%d%f%d″, &num1, &num2, &num3); //其中 %d 和 %f 均为转换说明符,分别表示读取的数据为整型和浮点型。
如果命令行输入为:12 34.5 678
,则该函数执行的效果是:系统读取整数12并赋值给 num1,读取浮点数34.5并赋值给 num2,读取整数678并赋值给 num3。
scanf 函数常用的转换说明符如下表(省略%
):
类型字符 | 含义 |
---|---|
d | 十进制整型量 |
o | 八进制整型量 |
x | 十六进制整型量 |
u | 无符号十进制整型 |
i | 整型 |
f | 实型的小数形式 |
e | 实型的指数形式 |
g | f 和 e 的较短形式 |
c | 字符 |
s | 字符串 |
l 或 h | 放在任何整数转换说明符之前,用于输入 short 或 long 类型数据 |
l 或 L | 放在任何浮点转换说明符之前,用于输入 double 或 long double类型数据 |
printf 的输出格式控制
printf 函数按照指定的格式向屏幕输出数据。函数形式为:
printf (<格式控制串>, <参数列表>) ;
-
<格式控制串> 一般是一个字符串,描述输出数据的格式。格式控制串可以包含3种类型的字符:格式指示符、转义字符、普通字符(除格式指示符和转义字符外的其他字符)。其中:
-
格式指示符的作用是将参数列表中相应的输出数据转换为指定的格式输出
-
转义字符按照其含义输出相应的特殊符号
-
普通字符则按照原样输出
-
-
<参数列表> 存放输出数据列表,有多个输出数据时,中间用
,
分隔。格式指示符的数量、顺序与输出数据相对应。
printf 函数执行时,根据格式控制串中的格式指示符、转义字符和普通字符等,从左到右依次进行处理:遇到普通字符,则按照原样输出;遇到转义字符,则按照其含义输出相应的符号;遇到格式指示符,则将对应的输出数据按照格式指示符指定的方式输出。
格式指示符的一般形式为:
% <标志> <域宽> <精度> <转换说明符>
其中,<标志>
、<域宽>
和<精度>
都是可选项,可以不出现。
标志
printf 函数常用的标志如下表:
标志 | 含义 |
---|---|
- | 输出在域宽内左对齐 |
+ | 在正数值之前显示一个加号,在负数值之前显示一个减号 |
空格 | 在正数值之前显示一个空格 |
# | 与八进制转换说明符 0 一起使用时,在输出值之前加 0; 与十六进制转换说明符 x 或 X 一起使用时,在输出值之前加 0x 或 0X |
0 | 用 0 填充域宽 |
注意:多个标志可以联合使用。
域宽
域宽一般为一个整数,指明了数据输出的宽度。
-
如果数据实际长度小于域宽,则数据输出右对齐,即数据仍然按照域宽规定输出,在数据左边用空格补齐;
-
如果数据实际长度大于域宽,那么系统将自动突破域宽的限制,按照数据的实际长度进行输出。
注意,负号要占据一个字符位置。如果没有指明域宽,系统则按照数据的实际长度输出。
精度
精度一般也是一个整数,对于不同类型的数据,精度的含义也不一样。
- 对于整数,精度表示至少要输出的数字个数。
如果数据实际长度小于精度,则左边用0补齐,使得数据长度等于精度;如果数据实际长度大于精度,则自动突破精度限制,按照数据的实际长度输出。省缺情况下整数的精度为1。
- 对于浮点数,有两种情况。
①如果转换说明符为 e、E 和 f,精度表示小数点后的有效位数。如果数据小数部分的实际长度小于精度,则在右边补齐0,使得小数部分长度等于精度;如果数据小数部分的实际长度大于精度,则按照精度对数据进行舍入输出;
②如果浮点数的转换说明符为 g 和 G,精度表示打印数据的最大的长度。
- 对于字符串数据,精度表示字符串输出的最大长度。
如果输出字符串的实际长度小于精度,则按照字符串的实际长度输出;如果字符串的实际长度大于精度,则按照精度截取输出字符串开头的 n 个字符(假设精度为 n )输出。
转换说明符
转换说明符指明了输出数据的类型信息。printf 函数常用的转换说明符如下表:
类型字符 | 含义 |
---|---|
d | 十进制整型量 |
o | 八进制整型量 |
x | 十六进制整型量 |
u | 无符号十进制整型 |
i | 整型 |
f | 实型的小数形式 |
e | 实型的指数形式 |
g | f 和 e 的较短形式 |
c | 字符 |
s | 字符串 |
% | 输出%本身 |
l 或 h | 放在任何整数转换说明符之前,用于输出 short 或 long 类型数据 |
L | 放在任何浮点转换说明符之前,用于输出 long double类型数据 |
例如以域宽为10、右对齐的方式输出15,然后再输出换行符(\n
):
printf("%10d\n",15);
说出结果为:________15
(这里用_
代替空格,凸显结果,即输出结果也就是在15前面补充8个空格。)
编程要求
在右侧编辑器中的Begin-End
之间补充代码,对输入的两个非负整数(均小于 100000,数据由平台提供,两个数之间用一个空格隔开,需要你获取后即可使用)进行四则运算,使得输出的四则运算表达式是完整对齐的。具体输出格式要求如下:
-
两个整数各占5个字符的位置,如果整数不足5位,则第一个整数在前面用空格补齐,第二个整数在后面用空格补齐,运算符(+、 -、 *、 /、 =都是运算符)占1个字符,且运算符前后各留一个空格位置;
-
输出结果占10个字符位置,不足10位时前面用空格补齐。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
- 为了让空格显示的更直观,这里暂用下划线
_
表示空格
测试输入:9876 123
预期输出: _9876 + 123__ = ______9999
_9876 - 123__ = ______9753
_9876 * 123__ = ___1214748
_9876 / 123__ = ________80
测试输入:7777 12
预期输出: _7777 + 12___ = ______7789
_7777 - 12___ = ______7765
_7777 * 12___ = _____93324
_7777 / 12___ = _______648
//包含标准输入输出函数库
#include <stdio.h>
int main()
{int x;
int y;
scanf("%d%d",&x,&y);
printf("%5d + %-5d = %10d\n" ,x,y,x+y);
printf("%5d - %-5d = %10d\n" ,x,y,x-y);
printf("%5d * %-5d = %10d\n" ,x,y,x*y);
printf("%5d / %-5d = %10d\n" ,x,y,x/y);
return 0;
}
第3关:你好,生日
任务描述
本关任务:当输入一个生日时,如“1992 3 18”,程序输出相应的问好信息,如“Hello! 3 18 1992”
。
提示:使用流对象进行输入输出是 C++ 对 C 语言在 I/O 上的扩展,如果只想学习 C 语言,这一关可以跳过。
相关知识
C++ 预定义了一些 I/O 流对象来实现输入输出,这些 I/O 流对象关联相应设备(键盘、显示器等)并实现程序和设备之间的数据传输。
C++ 预定义的 I/O 流对象有4个:cout 、cin 、cerr 和 clog,其中:
-
cout 代表标准输出流,关联显示器;
-
cin 代表标准输入流,关联键盘;
-
cerr 和 clog 代表标准错误流,也关联显示器。
本关我们主要学习标准输入输出流。
标准输入输出流
cin 和流提取运算符>>
一起实现数据输入,cout、cerr 和 clog 和流插入运算符<<
一起实现数据输出。
例如:
int a,b;
cin >> a >> b; // 输入两个整数分别给 a 和 b
cout << a + b << " " << a - b; // 输出 a+b 和 a-b 的值,中间用空格隔开
由于流对象的输入输出功能在 iostream 类库中实现,流对象则在名字空间 std 中定义,所以要使用上述输入输出方法需要包含 iostream 类库和加载名字空间 std 。相应的语句为:
// 包含I/O流库iostream
#include <iostream>
// 加载名字空间std
using namespace std;
编程要求
在右侧编辑器中的Begin-End
之间补充代码,程序接收你的生日输入(数据由平台提供,输入格式为“年 月 日”),如“1992 3 18”,请你输出问好信息“Hello! 3 18 1992”(输出为“月 日 年”格式)。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:1949 10 1
预期输出:Hello! 10 1 1949
测试输入:2005 3 6
预期输出:Hello! 3 6 2005
// 包含I/O流库iostream
#include <iostream>
// 加载名字空间std
using namespace std;
int main()
{
// 声明三个变量,分别用来存储年、月、日
int y, m, d;
cin>>y;
cin>>m;
cin>>d;
cout<<"Hello!"<<" "<<m<<" "<<d<<" "<<y;
// 请在Begin-End之间添加你的代码,输入你的生日,并按指定格式输出信息。
/********** Begin *********/
/********** End **********/
return 0;
}
第4关:不同精度的PI
任务描述
本关任务:输出不同精度的PI(程序给出的PI值为 3.14159265358979323846)。
相关知识
流输入输出也可以进行格式控制, C++ 中是通过流操纵算子来实现的。流操纵算子是在头文件 iomanip 中定义的,因此要使用这些流操纵算子,必须包含该头文件。
// 包含流操作算子库
#include <iomanip>
C++ 的 iomanip 库提供了多种流操纵算子,来实现不同的格式控制功能,包括设置域宽、设置精度、设置和清除格式化标志、设置域填充字符、在输出流中插入空字符、跳过输入流中的空白字符等,下表为一些常用的流操作算子:
流操纵算子 | 功能描述 |
---|---|
setbase(b) | 以进制基数 b 为输出整数值 |
setprecision(n) | 将浮点精度设置为 n |
setiosflags(long) | 设置特定的格式标志位 |
setw(n) | 按照 n 个字符来读或者写 |
setfill(ch) | 用 ch 填充空白字符 |
flush | 刷新 ostream 缓冲区 |
ends | 输出空字符 |
endl | 输出换行符并刷新 ostream 缓冲区 |
ws | 跳过空白字符(用于输入) |
下面本关主要介绍setbase(b)
、setprecision(n)
、setiosflags(long)
和setw(n)
算子,剩下的同学们可以自己尝试。
控制进制基数
对于标准输出流 cout 可以使用 setbase 来设置输出整数的进制基数(只支持8、10、16进制),如:
// 以八进制形式输出整数 n
cout << setbase(8) << n << endl;
也可以直接使用流操纵算子 oct(八进制)、hex(十六进制)和 dec(十进制)直接控制输出整数的进制,如:
// 以十六进制输出整数 n
cout << hex << n << endl;
设置浮点数输出精度
流操纵算子 setprecision 或函数 precision 都可以设置浮点数输出的精度,其参数为输出浮点数的有效数字个数(包括整数部分和小数部分,如12.34的有效数字个数为4)。
例如按5位有效位输出12.3 * 3.578
的值:
cout << setprecision(5) << 12.3 * 3.578 << endl;
或者:
cout.precision(5);
cout << 12.3 * 3.578 << endl;
以上输出结果均为:44.009
设置辅助格式
流操纵算子 setiosflags 可以辅助设置流输入输出格式,其参数是该流的格式标志值,setiosflags 提供了不同的参数来支持不同的输入输出格式需求。
setiosflags 的格式标志值如下表格:
标志值 | 含义 |
---|---|
ios::skipws | 在输入中跳过空白 |
ios::left | 左对齐,用填充字符填充右边。 |
ios::right | 右对齐,用填充字符填充左边(缺省对齐方式)。 |
ios::dec | 以基 10(十进制)格式化数值(缺省进制) |
ios::oct | 以基 8(八进制)格式化数值 |
ios::hex | 以基 16(十六进制)格式化数值 |
ios::showbase | 以 C++ 编译器能读的格式显示数值常量 |
ios::showpoint | 按精度把后面的空白补 0 输出 |
ios::uppercase | 对于十六进制数值显示大写字母 A 到 F,对于科学格式显示大写字母 E。 |
ios::showpos | 对于正数显示正号(+) |
ios::scientific | 以科学格式显示浮点数值 |
ios::fixed | 以定点格式显示浮点数值 |
例如:
double x = 1.23;
cout << setprecision(5) << x << endl;
cout << setiosflags(ios::showpoint) << setprecision(5) << x << endl;
输出结果为:
1.23
1.2300
域宽
对于域宽,函数 width 和流操纵算子 setw 都可以实现对当前域宽(即输入输出的字符数)的设置。
-
如果输出的数据所需的宽度比设置的域宽小,空位用填充字符(默认为空格)填充;
-
如果被显示的数据所需的宽度比设置的域宽大,系统会自动突破宽度限制,输出所有位。
例如:
cin >> n;
cout << setw(6) << n << endl; // 以域宽输出 n,如果 n 不足位,前面补空格
更多关于 iomanip 库的使用可点击关键字进入了解:setprecision 、iomanip 、setprecision、fixed、showpoint的用法总结 。
编程要求
在右侧编辑器中的Begin-End
之间补充代码,以实现输出不同精度PI的功能。具体要求如下:
-
输入的数为一个小于 15 的非负整数 n ;
-
输出 5 个不同精度的PI,即小数点后面分别保留 n,n+1 ,n+2 ,n+3 ,n+4 位的PI,每个PI分别独占一行。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:4
预期输出: 3.1416
3.14159
3.141593
3.1415927
3.14159265
测试输入:10
预期输出: 3.1415926536
3.14159265359
3.141592653590
3.1415926535898
3.14159265358979
#include <iostream>
// 包含流操作算子库
#include <iomanip>
using namespace std;
// 定义常量PI,后面可以直接用PI代替后面的数值
#define PI 3.14159265358979323846
int main()
{
int n;
// 请在Begin-End之间添加你的代码,输入n,按不同的精度输出 PI。
/********** Begin *********/
cin>>n;
cout<<setiosflags(ios::fixed)<<setprecision(n)<<PI<<endl;
cout<<setiosflags(ios::showpoint)<<setprecision(n+1)<<PI<<endl;
cout<<setiosflags(ios::fixed)<<setprecision(n+2)<<PI<<endl;
cout<<setiosflags(ios::fixed)<<setprecision(n+3)<<PI<<endl;
cout<<setiosflags(ios::fixed)<<setprecision(n+4)<<PI<<endl;
/********** End **********/
return 0;
}