【问题标题】:Why does getchar make a call to printf stop working?为什么 getchar 调用 printf 停止工作?
【发布时间】:2012-05-02 02:39:24
【问题描述】:

我写了一个程序,它接受一个输入字符并输出那个字符,像这样

int ch = getchar();
printf("%c", ch);

效果和我预期的一样。然后我决定先欢迎并打印Hello

printf("Hello!\n");
int ch = getchar();
printf("%c", ch);

令我惊讶的是,这导致编译器抛出两个错误:

错误 C2065:“ch”:未声明的标识符
错误 C2143:语法错误:缺少“;”在“类型”之前

我不明白为什么添加第一行会导致这种情况发生。无论如何,我重构了程序以摆脱 int 声明,错误神奇地消失了。

printf("Hello!\n");
printf("%c", getchar());

发生了什么事?导致这些错误出现然后消失的魔法是什么?

【问题讨论】:

  • 你用的是什么编译器?此代码在 gcc 4.4.3 上无错误。
  • @AdamCadien 我正在使用 Visual Studio 2010 附带的任何版本的 MSVC。

标签: c io printf


【解决方案1】:

如果您使用的是较旧的 c 编译器,则必须先进行所有变量声明。试试:

int ch;
printf("Hello!\n");
ch = getchar();
printf("%c", ch);

【讨论】:

  • 事实上,大约 1985 年之前的 C 编译器要求在任何可执行语句之前,任何变量声明都必须位于作用域 ({}) 中的第一个位置。如果还有编译器在做这件事,它很容易被任何优秀的免费编译器替换,例如gcc
  • 哦,那么 Visual Studio C 编译器不支持 C99 功能吗?
  • @PeterOlson:应该。出现这样的错误需要非常旧的 MSC 版本。也许还有其他问题,比如缺少分号?
  • @wallyk:我认为 MS 非常不愿意采用 C99,因为它的更多开发人员使用 C++,并且更喜欢采用 C++11。
  • Microsoft Visual C 支持 ANSI C89,而不是 C99。您必须将声明放在函数/块的开头。对不起。
【解决方案2】:

在 C89 标准中不允许在块开始后创建新变量,但在较新的 C99 标准中允许

您使用的是较旧的编译器或不完全符合 c99 的编译器。
您的代码示例应该可以在任何好的编译器上正常工作。 Works on gcc-4.3.4


替代解决方案:

您可以通过两种方式摆脱问题:
在块的开头声明变量:

int ch;
printf("Hello!\n");
ch = getchar();
printf("%c", ch);

或者

创建一个用于声明变量的新块:

printf("Hello!\n");
{ 
    int ch = getchar();
    printf("%c", ch);
}

建议:

你真的应该改变你的编译器,因为如果我没记错的话,gcc 甚至在 c99 之前就支持它作为编译器扩展。

【讨论】:

    【解决方案3】:

    C99 之前的 C 版本不允许“混合声明和代码”,这意味着您必须在作用域的开头声明所有变量。与 C++ 编译器一样,现代 C 编译器允许混合声明和代码。一些非 C99 编译器甚至允许它作为扩展。

    我认为这是为了让编译器更容易确定堆栈上实际需要多少空间,或者类似的东西。

    【讨论】:

      【解决方案4】:

      很可能,您使用的是相当旧的 C 编译器。可能是支持 C89 的一种。 使用 so 会强制您在块中的任何内容之前声明任何变量(例如函数或主函数) 两条出路: 先声明 ch:

      int ch = getchar();
      printf("Hello!\n");
      printf("%c", ch);
      

      或者,更好的是,尝试更改您的编译器。您使用的是什么操作系统?视窗? Linux?麦克?

      另外,一个简短的说明。您正在使用 getchar 获取整数。

      尝试使用 scanf("%d", &ch),而不是 getchar。或者,如果您确实需要使用 getchar 并将其打印为 char,请将 ch 声明为 char 本身,如果您需要再次将其用作整数,请使用 itoa 函数,该函数将 char 转换为整数.

      【讨论】:

      • 这个答案没有任何意义,getchar() 返回int,所以chint 是有意义的。另外,您不需要使用itoa()int 转换为char
      • 我想你不明白我所说的使用 itoa() 是什么意思。如果他真的需要(由于代码中的某种原因)将 ch 用作 char 而不是 int,他可以使用 itoa() 将 char 转换回整数。
      猜你喜欢
      • 1970-01-01
      • 2020-07-30
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 2019-05-30
      相关资源
      最近更新 更多