flex 生成的代码不会打印到控制台

问题描述

我正在试验 flex 以试图更好地了解它的工作原理。我在 lex (.l) 文件中有这个:

date

暂时忽略单一规则(除非它是某种原因)我想知道为什么 main() 函数中的 printf 语句没有做任何事情。在挖掘生成的 lex.yy.c 文件后,我怀疑该行

%option noyywrap

%%
"a"   printf("Found an \"a\"");

%%

int main()
{
   printf("This is working");
   return 0;
}

可能是原因,虽然我说不出原因(并且在搜索为什么 flex 会这样做时我找不到任何东西)

我不仅希望理解这对 C 代码意味着什么,而且为什么 flex 会这样做。它似乎是抑制或重定向输出(可能是 yacc 代码?)。如有任何解释或某些信息的链接,我将不胜感激。

(除非这只是我的 C 代码被破坏了)

解决方法

如果您使用 puts 而不是 printf,则会自动为您添加换行符。使用 printf 打印不包含格式化转换的常量字符串是没有意义的。

当然,你可以自己做,把它改成

printf("This is working\n")

或:

printf("%s\n","This is working.");

甚至更好:

fprintf(stderr,"%s\n","This is working.");

(见下文)

如果你不输出换行符,你的输出可能只会留在 stdio 缓冲区中(尽管在 stdout 关闭时它应该被刷新)。此外,当输出的最后一位没有以换行符终止时,某些 IDE 的行为会很糟糕。 (吞下字符是一种常见症状。)总而言之,最好遵循以下准则。

一般来说:

  • 你应该总是用新行结束打印的行。

  • 您应该了解 stdout 行缓冲的后果,即在常见情况下,不将输出终止到 stdout 意味着它不会立即呈现。

  • 并且您应该养成使用 stderr 而不是 stdout 来记录消息的习惯,即使它们严格来说不是错误,将 stdout 留给处理后的输出您的程序(如果您想将输出通过管道传输到另一个实用程序)。与 stdout 不同,stderr(默认情况下)通常是无缓冲的,因此会立即显示输出。 (但你仍然应该在最后放一个换行符,而不是让光标悬在行的中间。)

    顺便说一下,

    fputs 不会自动写入换行符。但在文字字符串的情况下,它仍然比 fprintf 好。