fprintf,printf和sprintf之间的区别?


233

任何人都可以用简单的英语有关之间的差异说明printffprintf以及sprintf结合实例?

这是什么流?

在阅读有关“ C语言中的文件处理”的内容时,我确实对这三个方法感到困惑。


4
通过编写一些示例代码对它们进行试验。这是清楚了解它们之间区别的非常简单的方法。
Nawaz

14
优先使用snprintf()而不是sprintf()以避免愚蠢的缓冲区溢出。
Maxim Egorushkin 2011年

3
首选流或Boost格式化程序,以避免愚蠢的缓冲区溢出和令人讨厌的类型不安全的错误
John Dibling 2011年

7
@Maxim,当您提出一个有效点时,我会确保我的缓冲区不会溢出并将我的应用分解成碎片,这是安全的。如果流/提升格式化程序显示出引起明显的瓶颈,我将只看这些功能。:)
Moo-Juice

1
@Maxim:关键是,没有必要。我的代码不是瓶颈。5m / sec是交换发送的消息数量,而不是我们能够处理的消息数量。那么为什么要过早优化呢?
John Dibling 2011年

Answers:


237

在C语言中,“流”是一种抽象;从程序的角度来看,它只是字节的生产者(输入流)或使用者(输出流)。它可以对应于磁盘上的文件,管道,终端或其他一些设备(例如打印机或tty)。该FILE类型包含有关流的信息。通常,您不会FILE直接弄乱对象的内容,而只是将指向它的指针传递给各种I / O例程。

有三个标准流:stdin是指向标准输入流stdout的指针,是指向标准输出流stderr的指针,并且是指向标准错误输出流的指针。在交互式会话中,这三个通常引用您的控制台,尽管您可以将它们重定向以指向其他文件或设备:

$ myprog < inputfile.dat > output.txt 2> errors.txt

在此示例中,stdin现在指向inputfile.datstdout指向output.txtstderr指向errors.txt

fprintf 将格式化的文本写入您指定的输出流。

printf等效于fprintf(stdout, ...)将格式化的文本写入并写入标准输出流当前指向的任何位置。

sprintf将格式化的文本写到的数组(char而不是流)中。


4
“它只是字节的生产者(输入流)或消费者(输出流)。” 这些倒退了吗?生产者不会创建(输出)某些东西吗?问,因为我真的不知道。
Dave Voyles

6
@DaveVoyles:这些是从程序的角度来看的。输入流产生字节供您的程序读取;输出流消耗程序产生的字节。
John Bode

153

printf输出到标准输出流(stdout

fprintf转到文件句柄(FILE*

sprintf转到您分配的缓冲区。(char*


39

printf(“ format”,args)用于将数据打印到通常是计算机监视器的标准输出上。

sprintf(char *,“ format”,args)类似于printf。而是在标准输出(即监视器)上显示格式化的字符串时,它将格式化的数据存储在char指针(第一个参数)指向的字符串中。字符串位置是printf和sprint语法之间的唯一区别。

fprintf(FILE * fp,“ format”,args)再次类似于printf。在这里,代替在监视器上显示数据或将其保存为某些字符串,格式化的数据将保存在文件指针指向的文件中,该文件指针用作fprintf的第一个参数。文件指针是对printf语法的唯一补充。

如果将stdout文件用作fprintf中的第一个参数,则认为其工作等效于printf。


24

printf(...)等同于fprintf(stdout,...)

fprintf 用于输出到流。

sprintf(buffer,...) 用于将字符串格式化为缓冲区。

请注意vsprintfvfprintf还有vprintf


v我相信这些口味是非标准的
John Dibling 2011年

8
v味道很肯定C标准。
Fred Foo

@larsmans:嗯,好的。感谢您的纠正。这个问题曾被标记为[c ++]
John Dibling 2011年

2

您还可以使用vsnprintf()函数做非常有用的事情:

$ cat test.cc
#include <exception>
#include <stdarg.h>
#include <stdio.h>

struct exception_fmt : std::exception
{
    exception_fmt(char const* fmt, ...) __attribute__ ((format(printf,2,3)));
    char const* what() const throw() { return msg_; }
    char msg_[0x800];
};

exception_fmt::exception_fmt(char const* fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(msg_, sizeof msg_, fmt, ap);
    va_end(ap);
}

int main(int ac, char** av)
{
    throw exception_fmt("%s: bad number of arguments %d", *av, ac);
}

$ g++ -Wall -o test test.cc

$ ./test
terminate called after throwing an instance of 'exception_fmt'
  what():  ./test: bad number of arguments 1
Aborted (core dumped)

+1确实有用,但请注意这vsnprintf是一个非标准功能。我见过的大多数实现都实现了这个或类似的东西,但是它是特定于实现的。
John Dibling 2011年

1
@larsmans上面提到,实际上,这实际上是C标准的一部分,因此我将其取回来
John Dibling 2011年

2
这和C有什么关系?
2011年

2

打印

  1. printf用于在屏幕上执行输出。
  2. 语法= printf("control string ", argument );
  3. 与文件输入/输出无关

fprintf

  1. 它用于在FILE句柄指向的文件中执行写操作的fprintf。
  2. 语法是 fprintf (filename, "control string ", argument );
  3. 它与文件输入/输出关联

如果这是从其他地方引用的,则最好引用带有链接的来源,但一定要保留此处引用的文本。
SuperBiasedMan 2015年

0

fprintf这与流相关,与printf语句类似fprintf但不相关的语句流,即fprintf与文件相关


0

sprintf:将格式化数据写入内存中的字符串,而不是标准输出

sprintf的语法是:

#include <stdio.h>
int sprintf (char *string, const char *format
[,item [,item]…]);

这里,

字符串是指向内存中要写入数据的缓冲区的指针。

格式是指指向定义格式的字符串的指针。

每个项目都是一个变量或表达式,用于指定要写入的数据。

如果操作成功,则sprintf返回的值大于或等于零;换句话说,返回的是不计算终止空字符的已写入字符数,如果发生错误,则返回小于零的值。

printf:打印到标准输出

printf的语法是:

printf format [argument]…

sprintf()和printf()之间的唯一区别是sprintf()将数据写入字符数组,而printf()将数据写入标准输出设备stdout。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.