Linux操作系統—標準IO庫(4)(2015-8-6)
分類:Linux操作系統
格式化I/O和臨時文件
格式化I/O
格式化I/O的作用是:從輸入流讀取字符串並以指定的格式轉換成內存中的二進制數據,或者將內存中的二進制數據以指定的格式轉換成字符串並將轉換後的字符串寫入輸出流。
格式化輸出
可用printf系列函數進行格式化輸出處理,它們的原型爲:
#include <stdio.h>
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, ...);
各參數含義:
1. stream:流文件指針
2. format:格式輸出串
3. ..:輸出表項(項數根據format中的轉換控制符可變)
4. str:字符串緩衝區
5. size:字符串緩衝區大小
6. 返回值:成功返回格式化後的字符數(不包含’\0’)。若出錯返回一個負數
printf:將格式化數據寫到標準輸出
fprintf:將格式化的數據寫至指定的流
sprintf和snprintf:將格式化的字符送入str緩衝區
snprintf最多將size個字節(含’\0’)寫入緩衝區,並且保證最後一個字節是null。snprintf的返回值若大於等於size,則說明格式化的結果在輸出時被截斷了。例如:
char buf[5];
/* 執行以下語句後,n的值爲7 */
int n = snprintf(buf, 5, "abcdefg");
相比較sprintf和snprintf,優先使用snprintf,因爲sprintf不能指定緩衝區大小,不安全。
格式化輸入
可用scanf系列函數進行格式化輸出處理,它們的原型爲:
#include <stdio.h>
int scanf(const char *format...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
函數返回值:若成功,返回實際得到的輸入的項數。若出錯,則返回EOF
scanf:從標準輸入讀取格式化數據
fscanf:從指定的流讀取數據
sscanf:從str緩衝區讀取格式化數據
臨時文件
標準I/O庫提供了下列兩個函數以幫助創建臨時文件,它們的原型如下:
#include <stdio.h>
char *tmpnam(char *s);
FILE *tmpfile(void);
函數tmpnam產生一個與現在文件名不同的一個有效路勁名字符串。每次調用它時,它都產生一個不同的路徑名,最多的調用次數是TMP_MAX。TMP_MAX在stdio.h中被定義
如果s爲NULL,則所產生的路徑名存放在一個靜態區中,指向該靜態區的指針作爲函數值返回,下一次再調用tmpnam時,會重寫該靜態區
如果s不爲NULL,則認爲它指向長度至少是L_tmpnam個字符數組。所產生的路徑名存放在該數組中,是也作爲函數值返回
tmpfile創建並打開一個臨時的二進制文件流(類型wb+),在關閉該文件流或程序結束時將自動刪除這個文件。tmpfile函數的一般實現是先調用tmpnam產生一個唯一的路徑名,然後在使用完後用unlink函數刪除。
下面是一個小例子
#include <stdio.h>
int main(int argc, char *argv[])
{
char name[L_tmpnam], line[BUFSIZ];
FILE *fp;
printf("%s\n", tmpnam(NULL)); /* 創建一個臨時文件,並將文件名輸出 */
tmpnam(name); /* 創建第二個臨時文件 */
printf("%s\n", name); /* 將產生的文件名輸出 */
if ((fp = tmpfile()) == NULL){ /* 創建並打開一個臨時文件 */
printf("Fail to create temp file.\n");
return -1;
}
fputs("One line of output.\n", fp); /* 向臨時文件內寫入一行文本 */
rewind(fp);
if (fgets(line, sizeof(line), fp) == NULL){
printf("Fail to read file.\n");
fclose(fp);
return -1;
}
fputs(line, stdout); /* 從臨時文件讀出文本 */
return 0;
}
編譯並運行
biantiao@lazybone1994-ThinkPad-E430:~/桌面$ gcc -o tmp tmp.c
/tmp/ccxjIL5T.o:在函數‘main’中:
tmp.c:(.text+0x2e): 警告: the use of `tmpnam' is dangerous, better use `mkstemp'
biantiao@lazybone1994-ThinkPad-E430:~/桌面$ ./tmp
/tmp/fileUdQWGZ
/tmp/filemniLKf
One line of output.
biantiao@lazybone1994-ThinkPad-E430:~/桌面$
文件流和文件描述符
每個文件流都和一個底層文件描述符相關聯,可以通過調用fileno函數獲得相關聯的文件描述符。該函數的原型如下:
#include <stdio.h>
int fileno(FILE *stream);
函數fileno的唯一參數是已打開的文件流指針。函數執行成功時返回一個非負的文件描述符;失敗時返回-1,並設置errno指示具體錯誤。