【问题标题】:Hidden printable text隐藏的可打印文本
【发布时间】:2017-07-06 11:05:32
【问题描述】:

我构建了一个小程序,只需将文本从 input.txt 文件复制到 output.txt 文件。该命令没有明显问题:

./myCopier.txt < rand.txt > randout.txt

在 GCC89 编译器上,用于教学目的。

#include<stdio.h>

int main(void){
        int c;

        while ((c = getchar()) != EOF)
                putchar(c);

        /*The text in printf() does not appear anywhere*/

        printf("My theories and toughts!\n");
}

后来,我添加了printf(),以打印我对该程序如何工作的想法。即使使用限制性参数(-Wall),它也可以编译而不会出现错误或警告,但此文本不会出现在任何地方。在任何地方,我指的是output.txt 和标准输出。

我在想:

  1. 单独的命令./myCopier.exe 显然会创建一个无限循环。如果没有文本输入,就没有EOL 字符,因此永远无法到达print() 命令。
  2. 那么,为什么在提供输入时,printf() 命令没有明显效果呢?我希望来自printf() 的文本出现在标准输出上,就在循环关闭并创建output.txt 时。为什么没有发生?
  3. 我的理论是./myCopier.txt &lt; rand.txt &gt; randout.txt 不允许这样做。出于某种原因,它使程序仅将输入传输到输出,“忽略”一切并非来自输入。我对么?如果是,为什么?

如果你对更详细的问题感兴趣,这里是汇编代码:

http://text-share.com/view/79f31f38

【问题讨论】:

  • 另外,如果我没记错的话,在 C99 中引入了在 main() 中省略显式 return 语句的权限,这意味着按照 C89 标准,您的程序会调用未定义的行为。跨度>
  • @Worice 正如我所说,您可以通过在 unix 上按 CTRL+D 或在 Windows 上按 CTRL+Z 来从标准输入发出 EOF 信号以终止循环
  • @Worice 那么由于某种原因,输出缓冲区没有被刷新...fflush(stdout);printf() 之后是否可以使用 io-redirection?
  • @Worice 还是很奇怪,输出缓冲区应该在退出时隐式刷新!你究竟是如何编译和链接你的二进制文件的?
  • 扔掉你正在编译的任何旧垃圾,并获得符合标准的 GCC 版本。您应该能够编译为gcc -std=c11 -pedantic-errors -Wall -Wextra。除非您有非常特殊的要求,否则没有任何理由将您的代码编译为 GNU C/gnu90。

标签: c c89


【解决方案1】:

在 main() 中省略 return 语句会导致 C89/C90 中出现未定义的行为。

通常,从 main() 返回会强制刷新输出缓冲区。如果省略 return 语句,任何事情都可能发生。

  • 尝试按照 C90 的要求在 main() 的末尾添加 return 0。否则,c90/gnu90 模式下的 GCC 会警告您:“控制到达非 void 函数的结尾”。
  • 尝试添加fflush(stdout);

【讨论】:

  • 听起来不错,但 OP claimed in comments 添加了 return 语句但没有成功。可能是 OP 弄错了,忘记编译更改等等......
  • @DavidBowling 如果有明确的 return 语句,则程序需要刷新缓冲区,从而在那时(如果不是之前)将文本打印到标准输出。如果不是,则编译器不符合要求。
  • 同意,这也是我的第一个想法。只是指出OP的评论。
  • 从实现@Lundin 抽象出来的C 标准理论是正确的。但在现实世界中,W & L 上的 gcc 退出代码无论如何都会刷新缓冲区。裸机实现大多没有(至少我使用的那些)。所以那些理论上毫无意义的讨论,在现实世界中根本没有帮助。
  • @PeterJ 这不是理论。 C 标准说从 main() 调用 return 与调用 exit() 函数是一回事。反过来说,在 exit() 时,必须刷新所有缓冲区。如果没有返回,那么你不能指望缓冲区被刷新,就这么简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 2021-11-04
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多