如何在C语言中从stdin读取一行后再次从stdin读取内容?

4

这个程序运行良好。

int main()
{
    {
        printf("Type something:\n");
        char* message = malloc(64 * sizeof(char));
        fgets(message, 64, stdin);
        printf("message ist : %s\n", message);
        free(message);
    }
}

但是当我运行以下程序时,它不允许我写任何内容,而是打印出:"message ist: "

int main()
{
    char action;

    while(action!='e')
    {
        printf("print a line: p\n");
        printf("End Program:  e\n");

        action = getc(stdin);

        if(action == 'p')
        {
            fflush(stdin);
            printf("Type something:\n");
            char* message = malloc(64 * sizeof(char));
            fgets(message, 64, stdin);
            printf("message ist : %s\n", message);
            free(message);
        }
        else if(action == 'e')
        {
            printf(" Program ended successfully\n");
            exit(0);
        }
    }
}

有人能解释一下为什么第一个程序让我输入,而第二个程序却不行吗?

我试过清空键盘缓冲区,但没有用。

我尝试使用getline()替代fgets(),结果相同。

非常感谢任何想法和解释。


现在是时候开始调试了。你已经调查了action的值吗?顺便说一下,fflush(stdin)是未定义行为。 - klutt
1
当您键入“p”时,实际上键入的是“p<ENTER>”。那个“<ENTER>”是fgets()看到的唯一字符。 - pmg
你可能希望初始化"action"而不是将其与未知值进行比较:"char action = 0;" - pmg
1
@klutt: 在没有扩展的实现中,fflush(stdin); 确实是未定义行为。例如,Windows库通过定义 fflush(stdin);(可能还有其他内容)来扩展C。但我从不使用它,我认为没必要依赖扩展是不好的。 - pmg
@pmg 如果他们知道他们正在使用一个扩展程序,那么他们可以忽略这样的建议。如果他们不知道,那么告诉他们是一件好事。 :) - klutt
2个回答

1
#include <stdio.h>

void customFlush()
{
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

int main()
{
    char action;
    char message[64] = { };

    while(action != 'e')
    {
        printf("---------\nCommands:\n'p' for print a line\n'e' for end program\n\nType a command: ");
        action = getc(stdin);
        // Exclude unnecessary chars (<Enter> and so on)
        customFlush(); // or fseek(stdin, 0, SEEK_END);

        if (action == 'p')
        {
            memset(message, 0, sizeof(message));
            printf("\nType something:\t");
            fgets(message, 64, stdin);
            printf("\nTyped message:\t%s\n", message);
            // Here is also possible place for calling customFlush or fseek()
        }
    }
    printf("Program ended successfully\n");
}

0
似乎fflush(stdin)(如上所述未定义)无法正常工作。问题在于缓冲区中仍然存在'\n',必须将其移除。否则,fgets被调用后会在缓冲区中找到'\n'(标记输入结束),然后继续执行程序。

请尝试使用以下代码:

    // fflush(stdin);
    while (getchar() != '\n');
    printf("Type something:\n");
    char* message = (char*) malloc(64 * sizeof(char));
    fgets(message, 64, stdin);
    printf("message is : %s\n", message);
    free(message);

同时也可以(虽然可能是不经意的)使用像“p MyMessage”这样的输入。 这确实会打印出消息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接