问题描述
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void eat() // clears stdin upto and including \n OR EOF
{
int eat;while ((eat = getchar()) != '\n' && eat != EOF);
}
int main(){
printf("\n COMMAND : "); char cmd[21]=""; scanf("%20s",cmd);
if(strcmp(cmd,"shell")==0||strcmp(cmd,"sh")==0)
{
getchar(); // absorb whitespace char separating 'shell' and the command,say 'ls'
while(1)
{
printf("\n sh >>> "); // print prompt
char shellcmd[1024]=""; // str to store command
scanf("%1023[^\n]",shellcmd); eat(); // take input of command and clear stdin
if(strcmp("close",shellcmd)==0||strcmp("x",shellcmd)==0)
break;
else
system(shellcmd);
}
}
}
在代码中,发生了一些我无法捕捉到的异常行为。
输入sh ls
并按[ENTER]
后,预期响应为:
- 第一个
scanf()
将sh
存储在cmd[]
中,并将ls\n
保留在stdin
中。 -
getchar()
占用 -
printf()
将\n sh >>>
打印到终端机 - 第二
scanf()
将ls
存储在shellcmd[]
中,将\n
保留在stdin中 -
eat()
从标准输入读取\n
,将其留空 -
system("ls")
被执行
即结果应该是这样的:
COMMAND : sh ls
sh >>>
file1 file 2 file3 ...
sh >>> | (cursor)
但是
我得到的是
COMMAND : sh ls
file1 file2 file3 ...
sh >>>
sh >>> |
显然,第二个scanf()
和shell()
正在之前 printf()
执行,或者至少是我的假设。 >
什么不对?
使用cc -Wall -Wextra -pedantic
在Clang和GCC上进行了编译,并在MacOS和Linux上的bash上进行了测试