10.23 晚自习 字符数组动态分配和scanf函数输入后的缓冲区

发布于 2024-10-23  213 次阅读


输入1个正整数n,在输入n个字符,分别统计其中英文字母、空格或回车、数字字符和其他字符的个数


这道题第二次做,多了个回车的条件,不过不影响,fgets函数具有读取空格和回车键的能力

first of all 你需要引入输入输出头文件<stdlib.h>,malloc要用,但fgets不用,它就在标准库里面

char *arr = malloc((n + 1) * sizeof(char)); // +1 用于存储字符串结束符

首先,请不要忘记指针arr的前面的*,而且这里必须是char类型,因为fgets函数只能处理字符(串)类型

请记住,char与malloc括号里面的sizeof(这个)必须一致因为malloc括号里面整个干的事情就是动态分配 *arr的大小


n + 1 是为了确保我们有足够的空间来存储 n 个字符以及一个额外的字符,用于存储字符串结束符 \0

 // +1 用于存储字符串结束符

  • 在C语言中,字符串是以 \0(空字符)结尾的(记住,并不是\n,这很合理)。这是一个特殊的字符,用于标识字符串的结束。
  • 因此,如果用户输入 n 个字符,我们需要为这个结束符额外分配一个字节的空间

例子

假设用户输入 n = 5,那么我们需要存储 5 个字符和一个结束符 \0。所以我们需要分配的内存大小是 5 + 1 = 6 字节

fgets(arr, n+1, stdin);

fgets括号里面第二个n+1: 这是需要读取的最大字符数(包括结束的空字符 \0)。换句话说,fgets 会读取最多 n-1 个字符,并在最后添加一个空字符以终止字符串。(和数组溢出有点类似)

所以,两个地方都需要用n+1

同时,遍历整个字符串的循环条件可以是for (int i = 0; arr[i] != '\0'; i++)

!='\0'这样最科学!


最后补上

free(arr); // 释放动态分配的内存

这里的arr不需要加* (其实目前就只有一处加,就是第一次的时候)


还有麻烦的地方,就是缓冲区的知识

char* arr = malloc(n+1);//应该是(n+1)*sizeof(char),但右边就是1,总所周知
scanf("%d", &n);
fgets(arr, n+1, stdin);

如果是这样写的,必定会报错

因为scanf读取输入后不会清除输入缓冲区中的换行符,这可能会导致后续使用 fgets 时出现问题。

char* arr = malloc(n+1);//应该是(n+1)*sizeof(char),但右边就是1,总所周知
scanf("%d", &n); 
getchar();
fgets(arr, n+1, stdin);

两个输入函数的中间加上getchar();就好了

因为scanf输入后你的换行符仍然在输入缓冲区中 ,需要清空缓冲区

getchar(); 的意思是读取并丢弃换行符

正好能清空scanf读取数据后的缓冲区

届ける言葉を今は育ててる
最后更新于 2024-11-05