程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言格式化輸出函數及使用禁區

C語言格式化輸出函數及使用禁區

編輯:關於C語言

C語言格式化輸出函數及使用禁區


編譯環境:
Debian: 7.6
gcc: 4.7.2
一、格式化輸出函數 C語言中設計到的標准格式化輸出函數如下:
#include 
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 
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);

二、相互之間的關系 1、共同點: 在格式化字串的控制下,把數據輸出到輸出設備。格式化字串指定如何把後續的參數進行轉化。如:
printf("%02x", 100);    /* 輸出是16進制 */
printf("%dx", 100);     /* 輸出是10進制 */

2、不同點: 按輸出到的設備分: printf() vprintf() 輸出至標准輸出流stdout fprintf() vfprintf() 輸出至指定輸出流 sprintf() snprintf() vsprintf() vsnprintf() 輸出至字串str
按是否指定操作字節分: snprintf() vsnprintf() 寫入至多size個字節(含'\0')到dtr vprintf() vfprintf() vsprintf() vsnprintf() 分別等同於:printf() fprintf() sprintf() snprintf() 區別是:它們都有va_list列表,一旦調用完畢,ap即成為“未定義”狀態
3、返回值: 正常情況下,函數返回輸出成功的字符個數(不含'\0')。若出錯,返回負值。 snprintf()和vsnprintf()輸出字符個數不超過size字節(含'\0'), 如果size小於字符串的長度(不含'\0'),字符串會被截斷,返回值是字符串的長度(不含'\0'),如下: int len; char str_buf[100]; len = snprintf(buf, 10, "%s$", "1234567890123"); // len: 13, buf: "1234567890"
如果size大於數據緩沖區長度,緩沖區長度個字串會被復制,返回值是字符串的長度(不含'\0'),如下: char str_buf[5]; // len: 13, buf: "12345"
三、使用注意 1、在使用sprintf()和vsprintf()的時候,應確保數據大小不超出str緩沖區的大小,否則產生溢出,造成災難。如果無法保證,應該選用snprintf()和vsnprintf()。
2、把字串加到原字串的後面,如下: sprintf(buf, "%s append text", buf); 在我用的gcc中,這種使用如期運行;但是,在有的gcc版本中,結果並不正確。所以,不要這樣做。 而且,標准中明確指出,調用sprintf(), snprintf(), vsprintf(),vsnprintf()函數,如果源、目標地址重疊,結果是未定義的(undefined). 3、像這樣的代碼printf(foo);往往會引入bug。因為如果foo中包含“%n”將引起printf()對內存的寫入並造成安全漏洞。例如: printf("%n"); // Segmentation fault

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved