C语言fgets读取超长字符串溢出到后续调用的问题如何修复
问题产生原因
fgets的读取规则限制:fgets(buf, size, stdin)最多读取size-1个字符存入目标缓冲区,遇到换行符/EOF就停止读取,未读取完的输入内容会残留在标准输入(stdin)的缓冲区中。- 你代码中第一次调用
fgets(stringa, 257, stdin)时,如果用户输入的字符串长度超过256字符,fgets只会读取前256个字符存入stringa,剩余的所有输入内容(包括末尾的换行符)会留在stdin缓冲区。 - 后续代码执行到选择操作的
fgets(a, 300000, stdin)时,会直接读取缓冲区中残留的内容,不会等待用户手动输入,残留内容的首字符大概率不是1/2/3,就会直接触发default分支的非法输入提示。 - 额外潜在问题:处理完的字符串
stringakek没有手动添加\0字符串终止符,输出时可能出现乱码。
修复方案
- 第一次读取用户输入后,清空stdin缓冲区的残留内容,确保后续的
fgets会等待用户新输入。 - 给处理后的
stringakek添加字符串终止符,避免输出乱码。
修复后的完整代码
#include <stdio.h> #include <ctype.h> #include <string.h> int main(void) { printf("your string:\n"); char stringa[257]; fgets(stringa, 257, stdin); // 清空stdin缓冲区残留内容 int c; while ((c = getchar()) != '\n' && c != EOF); for (int i = 0; stringa[i]; i++) { stringa[i] = tolower(stringa[i]); } char stringakek[257]; int j= 0; for (int i = 0; stringa[i]; i++) { if (stringa[i] >= 'a' && stringa[i] <= 'z') { stringakek[j] = stringa[i]; j++; } } // 添加字符串终止符 stringakek[j] = '\0'; printf("this is your string all in lowercase and containing only letters: %s\n", stringakek); printf("what do you want to do?\n"); printf("press 1 for case 1\n"); printf("press 2 for case 2\n"); printf("press 3 for case 3\n"); int controllo = 0; char a[300000]; while (controllo == 0) { fgets(a, 300000, stdin); switch(a[0]) { case '1': printf("case 1\n"); controllo = 1; break; case '2': printf("case 2\n"); controllo = 1; break; case '3': printf("case 3\n"); controllo = 1; break; default: printf("insert a valid input\n"); break; } } return 0; }
内容的提问来源于stack exchange,提问作者Gio Bur
相关产品推荐
相关产品推荐

