【问题标题】:printf done after getchar, while being placed before [duplicate]printf 在 getchar 之后完成,而放在 [重复] 之前
【发布时间】:2017-08-31 17:40:01
【问题描述】:

好的,所以我正在尝试制作一个“读取字符”功能,它只接受大写或小写字母,而不是重音符号(我是法国人,所以它对法国键盘很重要)并将其返回为大写字母。 为此,我为 readcharacter 函数制作了另一个源文件:

char readCharacter()
{
    char character;

    do
    {
        printf("Please enter a letter without accents and hit 'enter': ");

        character = getchar();
        while(getchar() != '\n');

        printf("\n");

        character = toupper(character); //Upper-case if lower case
    } while(((character < 65)||(character > 90)));
    return character;
}

这是我的主要内容:

#include "main.h"
int main(void)
{
    char MyLetter = readCharacter();
    char MyLetter2 = readCharacter();
    printf("%c\n%c\n", MyLetter, MyLetter2);
}

我的问题是,我得到了这个作为输出:

S
l
Please enter a letter without accents and hit 'enter': 
Please enter a letter without accents and hit 'enter':
S
L

为什么我没有得到这个?

Please enter a letter without accents and hit 'enter':S 
Please enter a letter without accents and hit 'enter':l
S
L

不知道这是否相关,但我的 IDE 是 eclipse,编译器是 MinGW(gcc?) 抱歉英语不好和/或编码不好...我刚刚开始编码... 谢谢!

【问题讨论】:

  • 请注意getchar实际上返回一个int
  • 至于你的问题,能否详细说明一下?你展示了你得到的输出,但是你期望的输出是什么?您是否尝试过在调试器中单步执行您的代码?也许您应该花点时间阅读 Eric Lippert 的 How to debug small programs
  • 编辑了预期的输出:)
  • 是的,我知道,但实际上不是 int 也是 char 吗?感谢 ascii 表?
  • 很好地阅读了为什么你应该尊重getchar()的返回值类型:stackoverflow.com/questions/35356322/…。长话短说,EOF 会造成麻烦,在某些情况下,某些字符可能会被解释为 EOF。成功时getchar() 等将字符值返回为 unsigned char,转换为 int。

标签: c eclipse


【解决方案1】:

问题是输出到stdout(由printf 使用)默认情况下是行缓冲。这意味着缓冲的输出仅在有换行符、缓冲区已满或您明确刷新它时才会写入。

由于您的函数中没有发生任何这些,因此输出只是“延迟”,直到它被您在 main 函数中打印的换行符刷新。

有两种解决方案:

  1. readCharacter 函数中打印的字符串末尾添加换行符;
  2. 或在调用printf 之后调用fflush(stdout) 刷新缓冲区。

【讨论】:

  • 好的,我添加了 fflush(stdout),它工作得很好,谢谢大家,很抱歉重新发布现有问题:我没有用我认为的合适的关键字来寻找他们!
【解决方案2】:

您需要小心不打印\n 的交互式程序,因为输出的缓冲时间可能比您需要的时间长。

printf 之后添加对fflush(stdout) 的调用,或在打印的字符串末尾添加\n 以解决此问题。

请注意,按 Ctrl+D(在 Windows 上为 Ctrl+Z)会打开等待'\n' while(getchar() != '\n'); 进入无限循环。

另请注意,您可以通过使用 !isupper(character) 来避免与字符代码(例如 character &lt; 65)进行数字比较。

【讨论】:

【解决方案3】:

您过滤'\n' 的算法是错误的,您可能需要在printf 之后刷新输出缓冲区。

你想要这个:

char readCharacter()
{
  char character;

  do
  {
    printf("Please enter a letter without accents and hit 'enter': ");

    fflush(stdout);  // may be not nessesary depending on your platform

    do
    {
      character = getchar();
    }
    while (character == '\n');

    printf("\n");

    character = toupper(character); //Upper-case if lower case
  } while ((character < 'A') || (character > 'Z'));

  return character;
}

我还将魔术数字 6590 替换为 'A''Z',这样更易​​读,因为如果清楚地表明您的意图。

【讨论】:

  • 嗨,谢谢你的回答!事实上,我不太明白我自己写的那一行:while(getchar() != '\n');,我认为这与每个人似乎都知道的缓冲区有关,除了他们从不在我遵循的教程中讨论它......你能详细说明为什么{ character = getchar(); } while (character == '\n');不一样吗?
猜你喜欢
  • 1970-01-01
  • 2020-10-05
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
相关资源
最近更新 更多