0

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

3 回答 3

0

使用fflush上面fgets..你需要stdin在输入消息之前刷新..

您可以使用__fpurgein linuxwhich is in stdio_ext 标头..

于 2013-04-10T12:52:31.920 回答
0

这个问题是你打电话fgets(),然后你打电话fflush()并做你的工作......然后你循环while并再次打电话fgets()......但你没有测试我只能保证你从中得到EOFfgets()现在你的while循环无休止地循环等待fgets()返回除了EOF

于 2013-04-10T12:55:39.303 回答
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在仅输入流上使用。

事实上,您甚至可以考虑阅读以前没有的功能手册页,特别注意“fgets”手册中标题为“返回值”的部分。您可能会以某种方式在循环的条件中包含该返回值,例如:

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

于 2013-04-10T13:47:22.167 回答