为何用strcmp()判断STDIN输入"exit"无效?原代码问题解析
为什么用
strcmp("exit", buf)无法正确检测输入? 嘿,我来帮你捋清楚这个问题——这其实是用C语言的read函数处理终端输入时非常容易踩的两个小坑!
核心问题1:read不会给缓冲区自动加字符串终止符
C语言里的字符串函数(比如strcmp)都要求目标字符串必须以\0(空字符)结尾才能正常工作,但read函数只是原封不动把字节读到缓冲区里,不会帮你加这个终止符。
举个例子:当你输入exit再按回车,read会把5个字节('e'、'x'、'i'、't'、'\n')塞进buf,但buf里没有\0。这时候strcmp会从buf开始一直读,直到找到\0为止,期间可能读到缓冲区里的残留垃圾数据,导致比较结果完全不可预测,自然没法正确匹配"exit"。
核心问题2:你的输入包含换行符
当你在终端输入完内容按回车时,回车会被转换成\n(换行符)一起被read读取。也就是说,你输入exit后,实际读到的内容是"exit\n"(5个字节),而你用strcmp和"exit"(4个字节,结尾是\0)比较,两者当然不相等——这也是为什么原来判断num_read==5会把所有4字母输入都当成退出指令,因为任何4个字符加回车都是5字节。
解决办法
只要把这两个问题处理掉,就能正常检测exit输入了:
给缓冲区手动添加字符串终止符
读取时要给\0留一个字节的位置,然后手动补上:#define BUF_SIZE 100 char buf[BUF_SIZE]; ssize_t num_read = read(STDIN_FILENO, buf, BUF_SIZE - 1); // 预留一个位置给\0 if (num_read == -1) { perror("read error"); exit(EXIT_FAILURE); } buf[num_read] = '\0'; // 手动添加字符串终止符去掉输入里的换行符
把缓冲区末尾的\n替换成\0,这样就能和"exit"精确匹配了:if (num_read > 0 && buf[num_read - 1] == '\n') { buf[num_read - 1] = '\0'; } if (strcmp("exit", buf) == 0) { printf("Exiting program...\n"); exit(EXIT_SUCCESS); }
这样修改后,只有当你输入exit并回车时,才会触发退出逻辑,其他4字母输入就不会误判啦。
内容的提问来源于stack exchange,提问作者static
相关产品推荐
相关产品推荐

