目录
前言:
开新专栏了,讲解100道基础语法编程题
用c语言讲解
目的是复习c语言中的基础语法,为单片机中的c语言代码分析做铺垫
专栏链接:
1、题目展示:
2、问题分析:
本题有几个新的以前没遇到的知识点
1、怎么保证输入第一个数如上面的2,可以换行再输入asdfasdf123123asdfasdf
解决方法:
int n; // 1. 声明整型变量n,用于存储测试用例个数
scanf("%d", &n); // 2. 读取用户输入的n值(如输入"2"后按回车)
int c; // 3. 声明整型变量c,用于临时存储字符
while ((c = getchar()) != '\n' && c != EOF); // 4. 清空输入缓冲区残留内容
1,2行是为了能够成功输入2,但是又面临一个问题,你输入完2之后要换行必然要输入换行符,但是换行符是一个字符,你后面要用fgets或者get_s函数的时候,会读取这个你输入在缓冲区的换行符
所以3,4行就是清理这个你人为输入的换行符,让下面的fgets或gets_s函数不要读取
下面我们具体来解释一下3,4行的含义
(c = getchar()) != '\n' && c != EOF
先执行c = getchar(),赋值符号满足右结合性,getchar函数用于读取缓冲区的字符,并返回与这个字符对应的一个整数并赋值给c
然后c与后面的!= '\n' && c != EOF进行判断
如果c的值对应的字符不是换行符或者程序结束符EOF那么就执行整个while语句的函数体
但是while语句的函数体没有内容,那么不执行任何操作,
比方说第一次判断条件判断语句,发现成立,然后执行函数体,但是函数体没有东西,那么再一次执行条件判断语句直至条件判断语句不成立
作用就是不断执行条件判断语句不断循环读取,以此清空缓冲区的所有字符
那么整个循环的流程是这样的
首先说明:一般如果有其他字符,换行符和EOF符是在最后面的
getchar函数不断从缓冲区读取字符,并判断是不是换行符和EOF符,如果是其一,则跳出循环不在执行while语句
此时前面如果有其他字符已经被读取了,读取出来就表示清除,此时遇到换行符和EOF符,在执行条件判断语句(c = getchar()) != '\n' && c != EOF的时候就已经被读取出来了,那么缓冲区就没有字符了
2、怎么判断一个字符串里面的数字的个数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
int n;
scanf("%d", &n); // 只读取一次n
// 清除输入缓冲区中的换行符
while (getchar() != '\n');
for (int i = 0; i < n; ++i) {
char str[100] = {0};
fgets(str, sizeof(str), stdin); // 安全读取含换行符的字符串
str[strcspn(str, "\n")] = '\0';//去除换行符
int count = 0;
for (int j = 0; str[j] != '\0'; ++j) {
if (isdigit(str[j])) {
++count;
}
}
printf("%d\n", count);
}
return 0;
}
第13行 定义了字符串,并设置长度为100,同时由于字符串是特殊的数组,所以对字符串进行元素的初始化
char str[100] = {0};表示数组所有元素初始化为 \0
(空字符),避免残留数据干扰,如果未初始化,数组可能残留之前的数据(如上一次循环的内容),同时保证最后一个字符为\0
14,15行读取字符串内容,注意头文件要包含#include <string.h>
fgets+str[strcspn(str, "\n")] = '\0';的优势:
-
明确指定缓冲区大小(
sizeof(str)
) -
fgets函数自动处理换行符(保留在字符串末尾)再用strcspn函数清理掉
-
兼容C99/C11标准,适用于更多平台
17-18行对于每一个不是空字符的字符进行是否是数字的判断,因为空字符'\0'会被当成数字0
利用了isdighit函数,注意头文件要包含#include <ctype.h>
3、最终代码展示:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
int n;
scanf("%d", &n); // 只读取一次n
// 清除输入缓冲区中的换行符
while (getchar() != '\n');
for (int i = 0; i < n; ++i) {
char str[100] = {0};
fgets(str, sizeof(str), stdin); // 安全读取含换行符的字符串
str[strcspn(str, "\n")] = '\0';//去除换行符
int count = 0;
for (int j = 0; str[j] != '\0'; ++j) {
if (isdigit(str[j])) {
++count;
}
}
printf("%d\n", count);
}
return 0;
}