口算练习题
题目描述
王老师正在教简单算术运算。细心的王老师收集了i道学生经常做错的口算题,并且想整理编写成一份练习。 编排这些题目是一件繁琐的事情,为此他想用计算机程序来提高工作效率。王老师希望尽量减少输入的工作量,比如 $\texttt{5+8}$ 的算式最好只要输入 $\texttt 5$ 和 $\texttt 8$,输出的结果要尽量详细以方便后期排版的使用,比如对于上述输入进行处理后输出 $\texttt{5+8=13}$ 以及该算式的总长度 $6$。王老师把这个光荣的任务交给你,请你帮他编程实现以上功能。
## 输入格式
第一行为数值 i
接着的 i 行为需要输入的算式,每行可能有三个数据或两个数据。
若该行为三个数据则第一个数据表示运算类型, a表示加法运算,b表示减法运算,c 表示乘法运算,接着的两个数据表示参加运算的运算数。
若该行为两个数据,则表示本题的运算类型与上一题的运算类型相同,而这两个数据为运算数。
输出格式
输出 2行。对于每个输入的算式,输出完整的运算式及结果,第二行输出该运算式的总长度
样例输入
```
4
a 64 46
275 125
c 11 99
b 46 64
```
样例输出
```
64+46=110
9
275+125=400
11
11*99=1089
10
46-64=-18
9
```
提示
数据规模与约定
对于 50\%的数据,输入的算式都有三个数据,第一个算式一定有三个数据。
对于所有数据,0<i\leq 50,运算数为非负整数且小于 10000。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main(){
int n; // 定义变量n,表示接下来要输入的数据行数
char a; // 定义字符变量a,用于存储是否为字母操作符
int c,d; // 定义整数变量c和d,用于存储操作数
char b[100],s[100]; // 定义字符数组b和s,用于存储输入和输出的字符串
cin>>n; // 输入数据行数
for(int i=0;i<n;i++){ // 循环n次,处理每一行输入
cin>>b; // 输入一个字符串b
if(b[0]<'0'||b[0]>'9'){ // 判断字符串的首字符是否为字母
a=b[0]; // 如果是字母,则将首字符赋值给变量a
cin>>c>>d; // 输入两个整数作为操作数
}else{
sscanf(b,"%d",&c);//将b转化为c的int型;
cin>>d;
}
memset(s,0,sizeof(s)); // 初始化数组s为全0
if(a=='a'){ // 判断a的值是否为字母'a'
sprintf(s,"%d+%d=%d",c,d,c+d); // 将c和d的和转为字符串存储到s中
}else if(a=='b'){ // 判断a的值是否为字母'b'
sprintf(s,"%d-%d=%d",c,d,c-d); // 将c和d的差转为字符串存储到s中
}else{
sprintf(s,"%d*%d=%d",c,d,c*d); // 将c和d的积转为字符串存储到s中
}
cout<<s<<endl<<strlen(s)<<endl; // 输出字符串s及其长度
}
}
运行结果:
sscanf(b,"%d",&c);
这行代码是使用sscanf函数将字符数组b中的字符串按照指定的格式进行解析,并将结果存储到变量c中。
具体来说,"%d"表示要匹配一个十进制整数,sscanf函数会尝试从字符串b中提取一个十进制整数,并将提取的结果存储到变量c中。
例如,如果字符串b中包含"123",那么经过sscanf函数解析后,变量c的值将被设为123。
需要注意的是,如果字符串b的格式与"%d"指定的格式不匹配(例如包含非数字字符),那么sscanf可能无法成功解析,并且变量c的值可能不会被正确设置。
memset(s,0,sizeof(s));
这行代码使用memset
函数将字符数组s
的所有元素初始化为0。它的作用是将一块内存区域设置为指定的值。
具体来说,memset
函数接受三个参数,分别是要设置的内存区域的起始地址、要设置的值以及要设置的内存区域的大小。
在这段代码中,memset(s, 0, sizeof(s))
的意思是将数组s
的所有元素都设置为0。s
是数组的起始地址,0是设置的值,sizeof(s)
表示要设置的内存区域的大小,即s
数组的总大小。
通过调用memset
函数将s
数组的所有元素设置为0,可以确保在每次使用s
数组之前,它不会保留上一次使用的旧数据,而是被正确初始化为0。这在某些情况下非常有用,例如在字符串处理中,确保字符串的结尾是以null字符’\0’结束,或者在需要清空数组内容时使用。
sprintf(s,"%d-%d=%d",c,d,c-d);
这行代码使用sprintf
函数将格式化的字符串存储到字符数组's'
中。
sprintf
函数的作用是根据指定的格式化字符串,将一组变量的值格式化成字符串,并将结果存储到指定的字符数组中。
具体来说,"%d-%d=%d"
是格式化字符串,其中%d
表示要替换为整数变量的占位符。c
和d
分别是要格式化的整数变量。c-d
是进行减法运算,得到的结果会替换成%d
部分的值。
在这个例子中,sprintf(s, "%d-%d=%d", c, d, c-d)
的意思是将格式化的字符串"%d-%d=%d"
中的%d
部分依次替换为变量c-d
的值,并将结果存储到字符数组s
中。
例如,如果c
的值为10,d
的值为5,那么sprintf(s, "%d-%d=%d", c, d, c-d)
的结果将是字符串"10-5=5"。这个字符串将会被存储到数组s
中。
cout<<s<<endl<<strlen(s)<<endl;
这段代码使用了cout
流输出字符数组s
和s
的长度。
cout
是C++标准库中的输出流对象,用于向控制台或其他输出设备输出数据。
<<
是输出流操作符,用于将数据插入到输出流中。
endl
是一个特殊的控制字符,表示换行,并刷新输出缓冲区。
strlen(s)
是一个C标准库函数,用于计算以null终止的字符串的长度。
所以,cout << s << endl << strlen(s) << endl;
的意思是,先输出字符数组s
的内容,然后换行,接着输出s
的长度,然后再换行。
请注意,在使用cout
输出字符数组时,它会假定's'
是以null字符'\0'
结尾的字符串。而strlen
函数正是根据null字符来计算字符串的长度。如果s
没有以null字符结尾或者含有其他无法正常显示的字符,输出结果可能会不准确。
该程序的功能是根据输入的不同格式,计算并输出相应的结果。输入的每一行都有可能有以下两种格式:
-
如果首字符为字母(即a、b、c之一),则说明输入的是字母操作符和两个整数操作数。根据字母操作符进行加法、减法或乘法运算,将结果输出为字符串,并输出字符串的长度。
-
如果首字符为数字,则说明输入的是两个整数操作数。直接将这两个整数相加,并将结果输出为字符串,并输出字符串的长度。
程序的执行流程如下:
- 输入一个整数n,表示接下来要输入的行数。
- 使用for循环,循环n次,处理每一行的输入。
- 在循环内部,先输入一个字符串b。
- 判断字符串的首字符是否为字母。
- 如果首字符是字母,则将首字符赋值给变量a,并继续输入两个整数操作数c和d。
- 如果首字符是数字,则将字符串b转换为整数,并赋值给变量c。然后继续输入一个整数操作数d。
- 使用memset函数将数组s初始化为空字符串。
- 根据变量a的值进行相应的计算,并使用sprintf函数将结果转换为字符串并存储到数组s中。
- 使用cout输出字符串s和它的长度(使用strlen函数计算)。
- 循环结束后,程序退出。
注意:该程序的注释已经说明了每个语句的功能,如果你有具体的问题,请提出。