【问题标题】:Issue with counting upper and lower letters in C在 C 中计算大小写字母的问题
【发布时间】:2020-09-17 01:13:26
【问题描述】:

我编写了一个程序,它应该计算大小写字母和其他符号,但除了单击 Enter 和 ^C (EOF) 之外,它会计算任何内容。我不知道如何跳过它,希望有人能以某种方式帮助我

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

int main()
{
  char ch;
  int uppers = 0, lowers = 0, others = 0;


  while((ch = getchar()) != EOF)
  {
    if(islower(ch))
      lowers++;

    else if(isupper(ch))
      uppers++;

    else
      others++;
  }

  printf("\n\nUpper letters - %d  Lower letters - %d   Others- %d", uppers, lowers, others);


  return 0;
}

【问题讨论】:

  • 使用 ^D 代替 ^C
  • 还有:char ch; --> int ch;
  • 你能解释一下原因吗?:0
  • 因为EOF 是一个定义为(-1) 的宏。如果保存到ch 中的字符值是255,它将与EOF 无法区分,因为对于8 位数据大小,它只是-1 的另一种表示。正如您在the docs 中看到的,getchar 的签名是int getchar (void) 而不是char getchar (void),因此将int 值分配给char 变量时会发生数据丢失。
  • 此外,根据系统架构,默认字符类型甚至可能是_unsigned。在这种情况下,情况正好相反——而不是255 值字符(例如我键盘上的字母ü)与EOF 无法区分,因为两者都被视为@ 987654339@ 在已签名 char,将来自getchar() 调用返回的EOFEOF (-1) 结果存储到unsigned char 变量中由于空间不足,它变成了实际的255,所以你最终会比较255 == -1,这绝不是真的。

标签: c while-loop counter


【解决方案1】:

Ctrl+C 发送一个SIGINT,通常只会终止您的应用程序。

你需要的是Ctrl+D,它会触发EOF。

编辑:请注意,在 Windows 的默认 shell 上,您可能需要 EnterCtrl+Z, Enter (或 F6)代替(虽然 Ctrl+Z 在 Linux shell 中完全做其他事情,发送SIGSTOP)。见this question

您还可以比较 0xD 而不是 EOF 来捕获 Enter,或者使用 0x1B 来捕获 Esc。这样您就可以避免在不同平台上触发输入结束的怪异现象(除非您想处理输入流)。

还可以查看上面的 this comment 以及 this answer,其中包含我遗漏的重要附加信息!

【讨论】:

  • 是的,EOF 可能依赖于操作系统,这就是为什么 ctrl + D 在 Windows 上不起作用。
  • 嗯,我猜你是在 Windows 上。更新了我的答案。
  • 是的,我在 Windows 上,所以这些选项都不起作用:/
  • 为什么不呢?与 Enter 或 Esc 或只是一个常规字符进行比较也是一个选项......
【解决方案2】:

CherryDt 已经提供了合适的答案。


不过补充一点,EOF 不是一个字符,而是一个结束条件。它可能取决于操作系统。您不能依靠它在每个环境中以相同的方式工作。我的建议是使用 any character 本身作为终止循环的条件,而不是依赖于环境的条件。

注意:只有当我在getchar() 之后包含fflush(stdin); 时,在Windows 上使用密钥结束程序的解决方案才对我有效。 getchar() 可能会接受您提供的输入,并在输入流中留下换行符 \n,当我尝试使用 ctrl+D 或 ctrl+ZF6

但是一旦你包含fflush(stdin),这将解决问题,现在当我在 Windows 上使用 F6 时程序成功结束。如果这对您不起作用,您也可以尝试使用上述密钥。

如果上述答案对他们不起作用,希望这对某些 Windows 用户有所帮助。

【讨论】:

  • 我才刚刚开始,您能否更具体地了解 fflush(stdin),我应该在哪里包含它?
  • 在 if-else 条件之外的 while() 循环中的任何位置使用它。我们只需要刷新输入流中的换行符,这可能会导致程序终止时出错。您可以在 while 循环结束之前将其包含在内,这样当使用 getchar() 进行下一个输入时,输入流中的换行符将不存在。
  • @ne0.exe 试试看它是否有效。一旦我包含了fflush(stdin);,它就可以使用 F6 键。
  • 天哪,唯一改变的是它甚至没有在输入字母的末尾显示 printf 只有 '^Z'
  • @ne0.exe 尝试 F6,然后按 Enter。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 2021-01-25
  • 1970-01-01
  • 2014-10-03
  • 1970-01-01
相关资源
最近更新 更多