在C语言中,如何使用'printf'将内容打印到标准错误输出?

206
在C语言中,使用stdio.h库的printf函数可以很容易地将内容输出到标准输出(stdout)。
然而,如何将内容输出到标准错误(stderr)呢?显然,我们可以使用fprintf函数来实现,但它的语法似乎有些奇怪。也许我们可以使用printf函数将内容输出到标准错误吗?

11
这个语法有什么奇怪的地方吗?它打印出 在哪里如何什么 - Eugene Sh.
7
我正在关注这件事。唯一的问题是,你对找到的解决方案感到“奇怪”。除此之外就没有问题了。请使用“fprintf”。 - Eugene Sh.
1
@Eugene。我同意你的看法。我觉得很奇怪,因为我没有意识到stderr是一个文件 :) - wad
也许perror(const char*)会有所帮助。 - Schilive
@Schilive感谢您告诉我 - 我现在也删除了我的。 - Per Lundberg
7个回答

294

语法与printf几乎相同。使用printf时,您需要提供字符串格式及其内容,例如:

printf("my %s has %d chars\n", "string format", 30);

使用fprintf也是一样的,只不过现在你还要指定打印的位置:

FILE *myFile;
...
fprintf(myFile, "my %s has %d chars\n", "string format", 30);

或者在你的情况下:

fprintf(stderr, "my %s has %d chars\n", "string format", 30);

58

一些标准输出和标准错误输出的格式化示例:

printf("%s", "Hello world\n");              // "Hello world" on stdout (using printf)
fprintf(stdout, "%s", "Hello world\n");     // "Hello world" on stdout (using fprintf)
fprintf(stderr, "%s", "Stack overflow!\n"); // Error message on stderr (using fprintf)

21
#include<stdio.h>

int main ( ) {
    printf( "hello " );
    fprintf( stderr, "HELP!" );
    printf( " world\n" );
    return 0;
}

$ ./a.exe
HELP!hello  world
$ ./a.exe 2> tmp1
hello  world
$ ./a.exe 1> tmp1
HELP!$
  1. stderr通常不带缓冲,stdout通常带缓冲。这可能导致看起来很奇怪的输出,比如下面这样的情况,它表明代码按错误的顺序执行了。实际上并非如此,只是stdout缓冲区尚未被刷新。 当输出被重定向或者管道后,就不会再出现这种交错的情况,因为它们通常只会看到stdout或stderr的输出。

  2. 虽然起初stdout和stderr都输出到控制台,但它们是分开的,可以单独重定向。


8
如果你不想修改当前的代码,只是为了调试使用。
添加这个宏:
#define printf(args...) fprintf(stderr, ##args)
// Under GCC

#define printf(args...) fprintf(stderr, __VA_ARGS__)
// Under MSVC

如果你想回滚,请将stderr更改为stdout
这对于调试很有帮助,但并不是一个好的做法。

2
你也可以给它一个单独的名称,比如 eprintf 或其他什么。(:O 这实际上是 GCC (3.2) 的可变参数宏示例: https://gcc.gnu.org/onlinedocs/gcc-3.2/cpp/Variadic-Macros.html) - Solomon Ucko
__VA_ARGS__并非特定于MSVC,因为它在C99的第6.10.3段第5节中有定义。 - undefined

2

3
这与 OP 无关,措辞令人困惑。sprintf 将“打印”到字符串中,无法打印到 stderr。 - David Ljung Madison Stellar

-1
由于某些原因,还没有人提到eprintf(),它与fprintf(stderr, ...)是相同的东西。
eprintf("ERROR: You have caused an error!!1!");

快速提示:如果您正在使用stderr进行调试,可以使用__LINE__宏。
#define printfError(str, ...) eprintf("ERROR at line " #__LINE__ ": " str, __VA_ARGS__)

printfError("Division by zero"); // "ERROR at line 2: Division by zero

4
没有人提到 eprintf,因为它不是标准的 C 库函数。 - Adrian Mole
2
@AdrianMole 哦。 - user13721385

-7
要打印您的内容,您可以编写类似以下代码的代码:
FILE *fp;
char *of;
sprintf(of, "%s%s", text1, text2);
fp = fopen(of, 'w');
fprintf(fp, "your print line");

这并没有为之前的回答增添任何内容,也没有真正回答问题。 - Fantastic Mr Fox
4
那个sprintf()语句会导致内存损坏!...我强烈建议您阅读有关指针,数组和字符串工作原理的相关知识。 - BlueChip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接