getchar()和fflush(stdin)的用法

时间:2016-09-28 04:38:56

标签: c

我应该想出一个程序来计算作业的单词,元音,小写字母和字母的数量。

我有两个问题,为什么我不能使用while (getchar() != '\n')而不是将其分配给变量ch以及为什么必须使用fflush(stdin) ???

    #include <stdio.h>
    #include <ctype.h>

    int main(void)
    {

        char ch, repeat;
        int numVowel = 0, numLower = 0, numAlpha = 0, numWords = 0, inWord = 0;

        // Tells user what the program does
        printf("This program prompts a user to enter a piece of text and\ncalculates the number of alphabetic letters, lowercase letters, \nvowels and words in that piece of text.\n\n");


        do
        {
             printf("Type the text here (hit \"Enter\" to end): ");  

             while ((ch = getchar()) != '\n')         //*dont understand this part*
            {
                    if (ch == ' ')                             
                        inWord = 0;

            else if (inWord == 0 && isalpha(ch))     
            {                                       
                inWord = 1;
                numWords += 1;
            }

            if (isalpha(ch))             
                numAlpha += 1;

            if (islower(ch))             
                numLower += 1;

            switch(ch)                   
            {
                case 'a':
                case 'A':
                case 'e':
                case 'E':
                case 'i':
                case 'I':
                case 'o':
                case 'O':
                case 'u':
                case 'U': numVowel += 1;
                          break;
            }
        }

        printf("\nNumber of alphabetical letters: %-4d\n", numAlpha);
        printf("Number of lowercase letters   : %-4d\n", numLower);
        printf("Number of vowels              : %-4d\n", numVowel);
        printf("Number of words               : %-4d\n\n", numWords);

        do
        {
            printf("Do you want to try again? (Y/N): ");

            scanf("%c", &repeat);
            repeat = toupper(repeat);
            if (repeat != 'Y' && repeat != 'N')         
                printf("Invalid answer. Please enter 'Y' or 'N'.\n\n");
            fflush(stdin);               //*why is this required?*               

        } while (repeat != 'N' && repeat != 'Y');       

        printf("\n");
        fflush(stdin);                   //*why is this required?*
        numVowel = 0, numLower = 0, numAlpha = 0, numWords = 0, inWord = 0;  

    } while (repeat == 'Y');           


    return 0;
}

2 个答案:

答案 0 :(得分:1)

  

为什么我无法使用while (getchar() != '\n')而不是将其分配给变量ch

如果这样做,您将无法在getchar()语句的代码块中使用while返回的值:if语句,{{ 1}}语句,else if语句。

  

为什么必须使用switch

fflush(stdin)用于输出流,而不是输入流。因此,fflush是未定义的行为。见http://en.cppreference.com/w/cpp/io/c/fflush 1

似乎代码中fflush(stdin)的意图是读取并丢弃所有内容,直到行结束。写一个函数来做到这一点。

fflush(stdin)

并使用

void readAndDiscardRestOfLine(FILE* in)
{
   int c;
   while ( (c = fgetc(in)) != EOF && c != '\n');
}

而不是

readAndDiscardRestOfLine(stdin);

1 POSIX扩展了输入流的fflush(stdin); 定义。但是,它仅将它们扩展到可搜索设备。该扩展程序不适用于fflush

答案 1 :(得分:-1)

使用scanf("%c", &repeat);扫描角色时会出现问题通常用户会输入角色&#39; y&#39;或者&#39; n&#39;然后按Enter键。该字符被读入repeat变量,但输入字符(\ n)仍保留在缓冲区中。

当您尝试再次阅读该字符时,您会在循环中阅读此\n而不是&#39; y&#39;或者&#39; n&#39;如你所料。

解决方法是将scanf语句更改为

scanf(" %c", &repeat);

%c的fromt中的空格字符将读取任何空格字符,并且只存储&#39; y&#39;或者&#39; n&#39;重复一遍。在这种情况下,您不需要fflush。

fflush(stdin)不是一个好习惯。有关详细信息,请查看Using fflush(stdin)