以下是我的C代码。第一个输入工作得很漂亮,但第二个输入导致无限循环。我冲刷了缓冲区,我没有任何线索如何解决这个问题。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define MAXARG 7
int main()
{
char buf[256];
char* arg[MAXARG];
char* s;
char* save;
int argv;
static const char delim[] = " \t\n";
int pid, status;
while(1){
printf("MyShell: ");
fgets(buf, sizeof(buf), stdin);
fflush(stdin);
argv = 0;
s = strtok_r(buf, delim, &save);
while(s){
arg[argv++] = s;
s= strtok_r(NULL, delim, &save);
}
arg[argv] = (char*) 0;
if(!strcmp(arg[0], "quit"))
break;
if((pid = fork()) == -1)
perror("fork failed...");
else if(pid != 0){
pid = wait(&status);
}
else{
execvp(arg[0], arg);
}
}
return 0;
}
答案 0 :(得分:0)
使用fflush
上方的fgets
..
你需要在输入信息之前刷新stdin
..
您可以在__fpurge
中的linux
使用stdio_ext标题中的{{1}}。
答案 1 :(得分:0)
此问题是您致电fgets()
,然后致电fflush()
并开始工作......然后您循环while
并再次致电fgets()
。但是你没有从EOF
测试fgets()
,我可以保证你得到它。现在,您的while
循环无休止地等待fgets()
返回EOF
以外的其他内容
答案 2 :(得分:0)
值得一提的是:当人们写 时,他们的意思通常是:fflush(stdin);
/* Read and discard the remainder of a line of input, because the remainder of
* the line isn't of interest to us...
*/
void discard_line(FILE *f) {
int c;
do {
c = fgetc(f);
} while (c >= 0 && c != '\n');
}
fflush
未定义为适用于stdin
等输入流。 可能正在做你期望的事情,但这只是巧合。如果您完全关心可移植性,则不会在仅输入流上使用fflush(stdin);
fflush
。
事实上,您甚至可以考虑阅读以前没有的功能的手册页,特别注意the section entitled "RETURN VALUE" of the "fgets" manual。您可以在循环条件中包含该返回值,不知何故,可能是:
/* Note how fflush is used on an output stream to ensure data is written
* immediately to stdout. You'll only need to do this when your data doesn't
* end in '\n', because data may not be written until a '\n' is written.
*/
printf("MyShell: "); fflush(stdout);
while (fgets(buf, sizeof buf, stdin) == buf) {
/* Find either the first '\n' or the first '\0', so we can work out whether
* or not to discard anything...
*/
size_t length = strcspn(buf, "\n");
if (buf[length] != '\n') {
/* If the line doesn't end in '\n', then we've read only part of a line.
* Discard the rest? Okay...
*/
discard_line(stdin);
}
/* Remove the '\n', if there is one. Otherwise, replace '\0' with '\0' ;) */
buf[length] = '\0';
/* TODO: Insert non-fflush(stdin)-related code here */
printf("MyShell: "); fflush(stdout);
}
PS。我建议阅读评论。他们可能很有见地。