问题描述
我正在试验 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
好。