Разница между fprintf, printf и sprintf?


233

Может кто - нибудь объяснить на простом английском языке о различиях между printf, fprintfи sprintfс примерами?

В каком потоке это?

Я действительно запутался между тремя из них, когда читал о "Обработка файлов в C".


4
Поэкспериментируйте с ними, написав пример кода. Это очень простой способ четко понять разницу между ними.
Наваз

14
Предпочитайте snprintf () sprintf (), чтобы избежать глупых переполнений буфера.
Максим Егорушкин

3
Предпочитайте потоки или средства форматирования Boost, чтобы избежать глупых переполнений буфера и неприятных ошибок, связанных с отсутствием безопасности типов
Джон Диблинг,

7
@ Максим, пока вы поднимаете действительную точку, я буду уверена в том, что мои буферы не будут переполнены и разнесут мое приложение на части. Я бы только посмотрел на эти функции, если бы было установлено, что потоковые / повышающие форматеры вызывают заметные узкие места. :)
Му-сок

1
@ Максим: Дело в том, что нет необходимости. Мой код не является узким местом. 5 м / с - это количество сообщений, которые отправляет обмен, а не то, сколько мы способны обработать. Так почему преждевременно оптимизировать?
Джон Диблинг

Ответы:


239

В C «поток» является абстракцией; с точки зрения программы это просто производитель (входной поток) или потребитель (выходной поток) байтов. Он может соответствовать файлу на диске, каналу, вашему терминалу или другому устройству, например, принтеру или tty. FILEТипа содержит информацию о потоке. Обычно вы не связываетесь с FILEсодержимым объекта напрямую, вы просто передаете указатель на него различным процедурам ввода / вывода.

Существует три стандартных потока: stdinуказатель на стандартный поток ввода, stdoutуказатель на стандартный поток вывода и stderrуказатель на стандартный поток вывода ошибок. В интерактивном сеансе эти три обычно относятся к вашей консоли, хотя вы можете перенаправить их, чтобы указать на другие файлы или устройства:

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

В этом примере stdinтеперь указывает на inputfile.dat, stdoutуказывает на output.txtи stderrуказывает на errors.txt.

fprintf записывает форматированный текст в указанный вами поток вывода.

printfэквивалентно записи fprintf(stdout, ...)и записи форматированного текста туда, куда в данный момент указывает стандартный поток вывода.

sprintfзаписывает форматированный текст в массив char, а не в поток.


4
«это просто производитель (входной поток) или потребитель (выходной поток) байтов». Это назад? Разве продюсер не будет создавать (выводить) что-то? Запрашиваемая, потому что я искренне не знаю.
Дейв Войлес

6
@DaveVoyles: это с точки зрения вашей программы. Входной поток производит байты для вашей программы для чтения; выходной поток потребляет байты, полученные из вашей программы.
Джон Боде

153

printfвыводит на стандартный поток вывода ( stdout)

fprintfидет к дескриптору файла ( FILE*)

sprintfидет в буфер, который вы выделили. ( char*)


40

printf («формат», args) используется для печати данных на стандартный вывод, который часто является монитором компьютера.

sprintf (char *, "format", args) похож на printf. Вместо отображения отформатированной строки на стандартном выходе, то есть на мониторе, он сохраняет отформатированные данные в строке, на которую указывает указатель на символ (самый первый параметр). Расположение строки - единственная разница между синтаксисом printf и sprint.

fprintf (FILE * fp, "format", args) снова похож на printf. Здесь вместо отображения данных на мониторе или сохранения их в какой-либо строке отформатированные данные сохраняются в файле, на который указывает указатель файла, который используется в качестве первого параметра для fprintf. Указатель файла является единственным дополнением к синтаксису printf.

Если файл stdout используется в качестве первого параметра в fprintf, его работа считается эквивалентной работе printf.


24

printf(...)эквивалентно fprintf(stdout,...).

fprintf используется для вывода в поток.

sprintf(buffer,...) используется для форматирования строки в буфер.

Примечание есть также vsprintf, vfprintfиvprintf


В vароматах нестандартные я считаю
Джон Dibling

8
Эти vароматы очень , конечно , в стандарте C.
Фред Фу

@ larsmans: ах, хорошо. спасибо за исправление. Этот вопрос был когда-то помечен [c ++]
Джон Диблинг

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это нестандартная функция. Большинство реализаций, которые я видел, реализуют это или что-то подобное, но это зависит от реализации.
Джон Диблинг

1
Выше @larsmans упоминает, что на самом деле это часть стандарта C, так что я возвращаюсь назад
Джон Диблинг,

2
Какое это имеет отношение к C?
один

2

Printf

  1. printf используется для вывода на экран.
  2. синтаксис = printf("control string ", argument );
  3. Это не связано с Файлом ввода / вывода

fprintf

  1. Fprintf, который он использовал для выполнения операции записи в файл, указанный дескриптором FILE.
  2. Синтаксис fprintf (filename, "control string ", argument );
  3. Это связано с вводом / выводом файла

Если это цитируется откуда-то еще, лучше всего сослаться на источник со ссылкой, но обязательно сохраняйте текст, который вы цитировали здесь.
SuperBiasedMan

0

fprintfЭто связано с потоками, где as 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.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.