最近刚刚学习了C基础这门课程,作到了这个习题,这个题目要求将字符串中的数字作为整数存放到整型数组中,这个题目有一个特点就是字符串中除了有数字还有非数int字符。看完题目,我顿时来了兴趣。
在一开始我选择用最笨的方法一步步分情况讨论,将各种情况考虑在内,编程过程中我发现情况比较复杂,一些限制条件导致语句列写的位置比较严格,逻辑结构比较繁复,在经过一些时间的思考后,我终于写出了如下的代码。
#include <stdio.h>
int main()
{
//定义数粗和一些参数
char ch[32] = {};
int a[32] = {}, i = 0, num = 0, sum = 0, j, t = 0;
//输入需要测试的字符
scanf("%s", ch);
char *p = ch, *q = p;
//将字符串中数字转成整形数据装进整形数组
while (*p != 0)
{
//当字符中出现其他类型数据时
if ((*p < 48 || *p > 57) && (*(p + 1) >= 48 && *(p + 1) <= 57))
{
sum = 0;
if ((*q < 48 || *q > 57) && t == 1)
i++;
else if (*q >= 48 && *q <= 57)
i++;
}
//将字符型数字转换成整型数
else
{
sum = sum * 10 + *p - 48;
num++;
t = 1;
a[i] = sum;
}
p++;
}
//打印整数的个数
printf("整数的个数为:%d\n", num);
//列出这些整数
printf("这些整数为:");
for (j = 0; j <= i; j++)
printf("%d", a[j]);
putchar(10);
//打印出这个数组
for (j = 0; j <= i; j++)
printf("a[%d]=%d ", j, a[j]);
putchar(10);
return 0;
}
首先是简单的定义和字符串的输入。其中num代表数字的个数,sum代表字符串中找出来的每一小段数字,i代表整型数组下标或者整形数组的元素个数,j用于for循环遍历数组,变量t可用于在不同情况下判断一部分代码块是否执行,q指针指向字符串的第一个字符,用于程序判断字符串的
//定义数粗和一些参数
char ch[32] = {};
int a[32] = {}, i = 0, num = 0, sum = 0, j, t = 0;
//输入需要测试的字符
scanf("%s", ch);
char *p = ch, *q = p;
随后定义了一个while循环结构,判断当指针指向‘0’即字符串结束时终止循环。在这个循环结构中遍历整个字符串,在指针指到不同的字符时分情况讨论。
在指针指到数字时,会执行这个语句块。其中sum = sum * 10 + *p - 48;可以在一个字符一个字符遍历下将各段数字字符作为数字保存下来,每执行这个语句块即每遍历到一个数字,数字个数num就会加一,最后遍历的次数就是数字的个数。
//将字符型数字转换成整型数
else
{
sum = sum * 10 + *p - 48;
num++;
t = 1;
a[i] = sum;
}
在指针指到非数int字符且下一个字符为数字字符时,就会执行如下语句块。
//当字符中出现其他类型数据时
if ((*p < 48 || *p > 57) && (*(p + 1) >= 48 && *(p + 1) <= 57))
{
sum = 0;
if ((*q < 48 || *q > 57) && t == 1)
i++;
else if (*q >= 48 && *q <= 57)
i++;
}
因为指到下一段数字字符数字应当重新计算,所以先将sum置零。当第一个字符为数字型字符时,会执行else if里面的语句,将整型数组下标加一,之后指针指到非数int字符时,继续将整型数组下标加一;当字符开头出现连续的非数int字符时,程序会进入到下一次循环,不进行其他操作,当判断到下一个字符为数字型字符时,由于t还是0,依旧不会进行其他操作,直接进入到下一次循环,指针指到数字时,会将t置为1,这样当指针再次指到非数int字符时,程序才会执行将数组下标加一。引入参数t可以避免在字符串开头是非数int字符时会使数组下标增加的错误。
最后就是打印出整数个数num,循环遍历打出这些整数和整型数组。
//打印整数的个数
printf("整数的个数为:%d\n", num);
//列出这些整数
printf("这些整数为:");
for (j = 0; j <= i; j++)
printf("%d", a[j]);
putchar(10);
//打印出这个数组
for (j = 0; j <= i; j++)
printf("a[%d]=%d ", j, a[j]);
下面来测试一下这个程序。
首先是字符串开头为数字型字符时:
![](https://img-blog.csdnimg.cn/img_convert/364f2e4e798d0753bc733643e63c79b2.png)
接下来是开头为非数int字符时:
![](https://img-blog.csdnimg.cn/img_convert/360fd300d9524e5b931bde6ec8bf642c.png)
纵观我写的这个程序,有多重嵌套,编写的时候语句的列写的位置也比较严格,勉强完成了程序,完成的时候有些些许沾沾自喜,直到第二天看到了老师写的程序。
#include<stdio.h>
int main(int argc, char const *argv[])
{
char buf[32]="a123b456";
int a[32]={};
int i=0,j=0,sum=0;
char *p = buf;
while(*p)
{
if(*p < '0'|| *p > '9')
{
p++;
continue;
}
while(*p >= '0'&&*p <= '9')
{
sum = sum*10 + *p -48;
p++;
}
a[i] = sum;
sum = 0;
i++;//存放整数的个数
}
printf("一共有%d个整数,他们分别是:\n",i);
while(j<i)
{
printf("%d ",a[j]);
j++;
}
printf("\n");
return 0;
}
老师这个continue用的十分巧妙,遇到非数int字符时直接在一开始跳过就可以,而且将各段数字的保存放到一个单独的循环体中,外部循环用于遍历每一段数字,内部循环用于遍历数字保存数字,对比我只写了一个循环进行一个字符一个字符遍历分情况讨论,无疑是简洁明了了不少,实在是令我受益匪浅。
在学习了老师的程序并和我的程序对比分析后,我明白了:在循环中,要善用循环控制语句,根据不同的情况使用continue和break可以让你的程序更加简单明了;对于一段一段的循环可以分开循环讨论,比起一个循环体,条件语句可以少很多。除此之外,我还明白了,程序需要多写多练,还要多多学习其他优秀程序的编程思想,积累编程经验。
编程小白,有不足之处请大佬们多多教导指正!