第二个输入char *进行无限循环

时间:2013-04-10 12:41:58

标签: c loops while-loop

以下是我的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;
}

3 个答案:

答案 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。我建议阅读评论。他们可能很有见地。