Sprintf_s, _sprintf_s_l, swprintf_s, _swprintf_s_l

SYNOPSIS top

       #include <stdio.h>

       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
       int dprintf(int fd, const char *format, ...);
       int sprintf(char *str, const char *format, ...);
       int snprintf(char *str, size_t size, const char *format, ...);

       #include <stdarg.h>

       int vprintf(const char *format, va_list ap);
       int vfprintf(FILE *stream, const char *format, va_list ap);
       int vdprintf(int fd, const char *format, va_list ap);
       int vsprintf(char *str, const char *format, va_list ap);
       int vsnprintf(char *str, size_t size, const char *format, va_list ap);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       snprintf(), vsnprintf():
           _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE ||
               || /* Glibc versions <= 2.19: */ _BSD_SOURCE

       dprintf(), vdprintf():
           Since glibc 2.10:
               _POSIX_C_SOURCE >= 200809L
           Before glibc 2.10:
               _GNU_SOURCE

Bugs

Because sprintf() and vsprintf() assume an arbitrarily long string, callers must be careful not to overflow the actual space; this is often
impossible to assure. Note that the length of the strings produced is locale-dependent and difficult to predict. Use snprintf() and vsnprintf()
instead (or asprintf(3) and vasprintf(3)).

Linux libc4. does not have a snprintf(), but provides a libbsd that contains an snprintf() equivalent to sprintf(), that is, one
that ignores the size argument. Thus, the use of snprintf() with early libc4 leads to serious security problems.

Code such as printf(foo); often indicates a bug, since foo may contain a % character. If foo comes from untrusted user
input, it may contain %n, causing the printf() call to write to memory and creating a security hole.

КомментарииRemarks

Функция sprintf форматирует и сохраняет последовательность символов и значений в буфере.The sprintf function formats and stores a series of characters and values in buffer. Каждый аргумент (при его наличии) преобразуется и выводится в соответствии с соответствующей спецификацией формата в формате.Each argument (if any) is converted and output according to the corresponding format specification in format. Формат состоит из обычных символов и имеет ту же форму и функцию, что и аргумент Format для printf.The format consists of ordinary characters and has the same form and function as the format argument for printf. После последнего написанного символа добавляется символ null.A null character is appended after the last character written. Если копирование производится между перекрывающимися строками, поведение не определено.If copying occurs between strings that overlap, the behavior is undefined.

Важно!

С помощью sprintfневозможно ограничить число записанных символов. Это означает, что код, использующий sprintf , уязвим для переполнения буфера.Using sprintf, there is no way to limit the number of characters written, which means that code using sprintf is susceptible to buffer overruns. Рассмотрите возможность использования функции _snprintf, которая указывает максимальное число символов для записи в буфер, или используйте _scprintf , чтобы определить, сколько требуется буфера.Consider using the related function _snprintf, which specifies a maximum number of characters to write to buffer, or use _scprintf to determine how large a buffer is required. Кроме того, убедитесь, что Формат не является определяемой пользователем строкой.Also, ensure that format is not a user-defined string.

swprintf — это версия sprintfдля расширенных символов; аргументы-указатели для swprintf являются строками расширенных символов.swprintf is a wide-character version of sprintf; the pointer arguments to swprintf are wide-character strings. Обнаружение ошибок кодирования в swprintf может отличаться от sprintf.Detection of encoding errors in swprintf may differ from sprintf. поведение swprintf и fwprintf идентично, за исключением того, что swprintf записывает выходные данные в строку, а не в назначение типа File, а swprintf требует параметр Count , чтобы указать максимальное число символов для записи.swprintf and fwprintf behave identically except swprintf writes output to a string rather than to a destination of type FILE, and swprintf requires the count parameter to specify the maximum number of characters to write. Версии этих функций с суффиксом _l идентичны, за исключением того, что они используют переданный параметр языкового стандарта вместо языкового стандарта текущего потока.The versions of these functions with the _l suffix are identical except they use the locale parameter passed in instead of the current thread locale.

swprintf соответствует стандарту ISO C, для которого требуется второй параметр, count, типа size_t.swprintf conforms to the ISO C Standard, which requires the second parameter, count, of type size_t. Чтобы принудительно использовать старое нестандартное поведение, определите _CRT_NON_CONFORMING_SWPRINTFS.To force the old nonstandard behavior, define _CRT_NON_CONFORMING_SWPRINTFS. В будущей версии старое поведение может быть удалено, поэтому код необходимо изменить в соответствии с новым стандартным поведением.In a future version, the old behavior may be removed, so code should be changed to use the new conformant behavior.

В C++ эти функции имеют шаблонные перегрузки, которые вызывают более новые и безопасные аналоги этих функций.In C++, these functions have template overloads that invoke the newer, secure counterparts of these functions. Дополнительные сведения см. в разделе Безопасные перегрузки шаблонов.For more information, see Secure Template Overloads.

Универсальное текстовое сопоставление функцийGeneric-Text Routine Mappings

Подпрограмма TCHAR.HTCHAR.H routine _UNICODE и _MBCS не определены_UNICODE & _MBCS not defined _MBCS определено_MBCS defined _UNICODE определено_UNICODE defined
_stprintf_stprintf sprintfsprintf sprintfsprintf _swprintf_swprintf
_stprintf_l_stprintf_l _sprintf_l_sprintf_l _sprintf_l_sprintf_l __swprintf_l__swprintf_l

NOTES top

       Some programs imprudently rely on code such as the following

           sprintf(buf, "%s some further text", buf);

       to append text to buf.  However, the standards explicitly note that
       the results are undefined if source and destination buffers overlap
       when calling sprintf(), snprintf(), vsprintf(), and vsnprintf().
       Depending on the version of gcc(1) used, and the compiler options
       employed, calls such as the above will not produce the expected
       results.

       The glibc implementation of the functions snprintf() and vsnprintf()
       conforms to the C99 standard, that is, behaves as described above,
       since glibc version 2.1.  Until glibc 2.0.6, they would return -1
       when the output was truncated.

Parameters

Sr.No. Specifier & Output
1

c

Character

2

d or i

Signed decimal integer

3

e

Scientific notation (mantissa/exponent) using e character

4

E

Scientific notation (mantissa/exponent) using E character

5

f

Decimal floating point

6

g

Uses the shorter of %e or %f

7

G

Uses the shorter of %E or %f

8

o

Signed octal

9

s

String of characters

10

u

Unsigned decimal integer

11

x

Unsigned hexadecimal integer

12

X

Unsigned hexadecimal integer (capital letters)

13

p

Pointer address

14

n

Nothing printed

15

%

Character

Sr.No. Flags & Description
1

Left-justify within the given field width; Right justification is the default (see width sub-specifier).

2

+

Forces to precede the result with a plus or minus sign (+ or -) even for positive numbers. By default, only negative numbers are preceded with a -ve sign.

3

(space)

If no sign is going to be written, a blank space is inserted before the value.

4

#

Used with o, x or X specifiers the value is preceded with 0, 0x or 0X respectively for values different than zero. Used with e, E and f, it forces the written output to contain a decimal point even if no digits would follow. By default, if no digits follow, no decimal point is written. Used with g or G the result is the same as with e or E but trailing zeros are not removed.

5

Left-pads the number with zeroes (0) instead of spaces, where padding is specified (see width sub-specifier).

Sr.No. Width & Description
1

(number)

Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.

2

*

The width is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.

Sr.No. .precision & Description
1

.number

For integer specifiers (d, i, o, u, x, X) − precision specifies the minimum number of digits to be written. If the value to be written is shorter than this number, the result is padded with leading zeros. The value is not truncated even if the result is longer. A precision of 0 means that no character is written for the value 0. For e, E and f specifiers − this is the number of digits to be printed after the decimal point. For g and G specifiers − This is the maximum number of significant digits to be printed. For s − this is the maximum number of characters to be printed. By default all characters are printed until the ending null character is encountered. For c type − it has no effect. When no precision is specified, the default is 1. If the period is specified without an explicit value for precision, 0 is assumed.

2

.*

The precision is not specified in the format string, but as an additional integer value argument preceding the argument that has to be formatted.

Sr.No. Length & Description
1

h

The argument is interpreted as a short int or unsigned short int (only applies to integer specifiers: i, d, o, u, x and X).

2

l

The argument is interpreted as a long int or unsigned long int for integer specifiers (i, d, o, u, x and X), and as a wide character or wide character string for specifiers c and s.

3

L

The argument is interpreted as a long double (only applies to floating point specifiers: e, E, f, g and G).

additional arguments − Depending on the format string, the function may expect a sequence of additional arguments, each containing one value to be inserted instead of each %-tag specified in the format parameter (if any). There should be the same number of these arguments as the number of %-tags that expect a value.

Example

The following example shows the usage of fprintf() function.

#include <stdio.h>
#include <stdlib.h>

int main () {
   FILE * fp;

   fp = fopen ("file.txt", "w+");
   fprintf(fp, "%s %s %s %d", "We", "are", "in", 2012);
   
   fclose(fp);
   
   return(0);
}

Let us compile and run the above program that will create a file file.txt with the following content −

We are in 2012

Now let’s see the content of the above file using the following program −

#include <stdio.h>

int main () {
   FILE *fp;
   int c;

   fp = fopen("file.txt","r");
   while(1) {
      c = fgetc(fp);
      if( feof(fp) ) {
         break;
      }
      printf("%c", c);
   }
   fclose(fp);
   return(0);
}

Let us compile and run above program to produce the following result.

We are in 2012

stdio_h.htm

Previous Page
Print Page

Next Page  

EXAMPLES top

       To print Pi to five decimal places:

           #include <math.h>
           #include <stdio.h>
           fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0));

       To print a date and time in the form "Sunday, July 3, 10:02", where
       weekday and month are pointers to strings:

           #include <stdio.h>
           fprintf(stdout, "%s, %s %d, %.2d:%.2d\n",
                   weekday, month, day, hour, min);

       Many countries use the day-month-year order.  Hence, an internation‐
       alized version must be able to print the arguments in an order speci‐
       fied by the format:

           #include <stdio.h>
           fprintf(stdout, format,
                   weekday, month, day, hour, min);

       where format depends on locale, and may permute the arguments.  With
       the value:

           "%1$s, %3$d. %2$s, %4$d:%5$.2d\n"

       one might obtain "Sonntag, 3. Juli, 10:02".

       To allocate a sufficiently large string and print into it (code cor‐
       rect for both glibc 2.0 and glibc 2.1):

       #include <stdio.h>
       #include <stdlib.h>
       #include <stdarg.h>

       char *
       make_message(const char *fmt, ...)
       {
           int n = 0;
           size_t size = 0;
           char *p = NULL;
           va_list ap;

           /* Determine required size */

           va_start(ap, fmt);
           n = vsnprintf(p, size, fmt, ap);
           va_end(ap);

           if (n < 0)
               return NULL;

           /* One extra byte for '\0' */

           size = (size_t) n + 1;
           p = malloc(size);
           if (p == NULL)
               return NULL;

           va_start(ap, fmt);
           n = vsnprintf(p, size, fmt, ap);
           va_end(ap);

           if (n < 0) {
               free(p);
               return NULL;
           }

           return p;
       }

       If truncation occurs in glibc versions prior to 2.0.6, this is
       treated as an error instead of being handled gracefully.

Synopsis

int printf(const char *format, …);
int fprintf(FILE *
stream, const char *format, …);
int sprintf(char *
str, const char *format, …);
int snprintf(char *
str, size_t size, const char *format, …);

#include <stdarg.h>

int vprintf(const char *format, va_list ap);
int vfprintf(FILE *
stream, const char *format, va_list ap);
int vsprintf(char *
str, const char *format, va_list ap);
int vsnprintf(char *
str, size_t size, const char *format, va_list ap);

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

snprintf(), vsnprintf():
_BSD_SOURCE || _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L;
or cc -std=c99

CONFORMING TO top

       fprintf(), printf(), sprintf(), vprintf(), vfprintf(), vsprintf():
       POSIX.1-2001, POSIX.1-2008, C89, C99.

       snprintf(), vsnprintf(): POSIX.1-2001, POSIX.1-2008, C99.

       The dprintf() and vdprintf() functions were originally GNU extensions
       that were later standardized in POSIX.1-2008.

       Concerning the return value of snprintf(), SUSv2 and C99 contradict
       each other: when snprintf() is called with size=0 then SUSv2
       stipulates an unspecified return value less than 1, while C99 allows
       str to be NULL in this case, and gives the return value (as always)
       as the number of characters that would have been written in case the
       output string has been large enough.  POSIX.1-2001 and later align
       their specification of snprintf() with C99.

       glibc 2.1 adds length modifiers hh, j, t, and z and conversion
       characters a and A.

       glibc 2.2 adds the conversion character F with C99 semantics, and the
       flag character I.

История появления[править]

Первые следы будущей функции появляются в языке BCPL в 1960-х. Функция принимает строку форматирования, в которой тип данных указывается отдельно от самих данных в строковой переменной (тип указывался без полей флагов, ширины, точности и размера, но уже предварялся символом процента %). Появившийся вслед за ним в 1969 году язык Би уже использовал название с простейшей строкой форматирования (аналогичной BCPL), указывался только один из трёх возможных типов и два представления числа: десятичные (%d), восьмеричные (%o), строки (%s) и символы (%c).

Основной целью появления строки форматирования была передача типов аргументов, так как для языков программирования со статической типизацией определение типа переданного аргумента для функции с произвольными типами аргументов требует сложного и неэффективного (по крайней мере во времена создания Си, механизма RTTI).

Единственной возможностью по форматированию вывода в этих функциях было добавление символов до и после вывода значения переменной.

Сама функция была средством упрощения вывода, вместо набора функций (вывод символа), (вывод строки), , , , (вывод чисел в различной форме) использовался единый вызов, в котором можно было чередовать «просто текст» с выходными значениями.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *