c裡面的printf, fprintf, sprintf, snprintf, printf_s, fprintf_s, sprintf_s, snprintf_s一問說清所有各種printf

zhjh256發表於2024-10-19

都定義在<stdio.h>中,有些事C99的一部分,有些事C11新加的。如下:

int printf( const char* format, ... );
(until C99)
int printf( const char* restrict format, ... );
(since C99)
(2)
int fprintf( FILE* stream, const char* format, ... );
(until C99)
int fprintf( FILE* restrict stream, const char* restrict format, ... );
(since C99)
(3)
int sprintf( char* buffer, const char* format, ... );
(until C99)
int sprintf( char* restrict buffer, const char* restrict format, ... );
(since C99)
int snprintf( char* restrict buffer, size_t bufsz,
const char* restrict format, ... );
(4) (since C99)
int printf_s( const char* restrict format, ... );
(5) (since C11)
int fprintf_s( FILE* restrict stream, const char* restrict format, ... );
(6) (since C11)
int sprintf_s( char* restrict buffer, rsize_t bufsz,
const char* restrict format, ... );
(7) (since C11)
int snprintf_s( char* restrict buffer, rsize_t bufsz,
const char* restrict format, ... );
(8) (since C11)

各個gcc編譯器版本對c標準的支援情況參見這裡

規則為:普通的printf就是列印,sprintf就是格式化用途、叫做messageformat更合適。fprintf就是指定流而不是使用stdout標準流。帶n版本為指定長度。帶s的版本為所謂的安全版。

所以簡單一點,格式化就用snprintf,寫檔案就用fprintf。

對應printf還有wprintf,vprintf,w\v代替f。w是寬字元。v版本和非v版本的區別在於,v版本自己管理可變引數。如下:

The functions vprintf(), vfprintf(), vdprintf(), vsprintf(),
       vsnprintf() are equivalent to the functions printf(), fprintf(),
       dprintf(), sprintf(), snprintf(), respectively, except that they
       are called with a va_list instead of a variable number of
       arguments.  These functions do not call the va_end macro.
       Because they invoke the va_arg macro, the value of ap is
       undefined after the call.

帶_s是所謂的安全版本,c11標準的一部分,會檢查引數,由宏__STDC_WANT_LIB_EXT1__控制。參見https://software-dl.ti.com/codegen/docs/tiarmclang/compiler_tools_user_guide/compiler_manual/compiler_security/C11_secure_functions.html,https://docs.oracle.com/cd/E88353_01/html/E37843/snprintf-s-3c.html

參考:https://en.cppreference.com/w/c/io/fprintf

https://www.man7.org/linux/man-pages/man3/vsnprintf.3.html

相關文章