文件流操作
目前主要介紹使用C函數操作文件流,之后待續。。。
讀取單個字符操作:
int fgetc (FILE * stream); // 從文件流中讀取一個字符。可將標準輸入stdin作為參數。 _Check_return_opt_ _CRTIMP int __cdecl fgetc(_Inout_ FILE * _File); int fputc (int character, FILE * stream); _Check_return_opt_ _CRTIMP int __cdecl fputc(_In_ int _Ch, _Inout_ FILE * _File); int getc (FILE* stream); // 與fgetc等效 _Check_return_ _CRTIMP int __cdecl getc(_Inout_ FILE * _File); int putc (int character, FILE * stream); _Check_return_opt_ _CRTIMP int __cdecl putc(_In_ int _Ch, _Inout_ FILE * _File); int getchar (); // 從標準輸入stdin讀入一個字符。相當于fgetc(stdin)。 _Check_return_ _CRTIMP int __cdecl getchar(void); int putchar(int character); _Check_return_opt_ _CRTIMP int __cdecl putchar(_In_ int _Ch);?
讀取字符串操作:
char * fgets (char * str, int num, FILE * stream); // 從文件流中讀取最多num個字符到字符數組str中, // 當遇到結束符(如換行符)或者讀到num - 1個字符時停止。 // 函數自動在末尾添加 '\0' 空字符。 _Check_return_opt_ _CRTIMP char * __cdecl fgets(_Out_z_cap_(_MaxCount) char * _Buf, _In_ int _MaxCount, _Inout_ FILE * _File); int fputs(const char * str, FILE * stream); _Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char * _Str, _Inout_ FILE * _File); char* gets (char * str); // no commend!!! // 從標準輸入stdin中讀取字符串,直到遇到結束符為止。 // 該函數未指定大小,所以一定要注意字符數組的大小。 _Check_return_ _CRTIMP char * __cdecl gets(char * _Buffer); int puts(const char * str); // no commend!!! _Check_return_opt_ _CRTIMP int __cdecl puts(_In_z_ const char * _Str);?
早期的Internet蠕蟲病毒的實現其中就用到了gets函數。該函數的任務是從文件流中讀入一個字符串。調用者將提供讀入的字符串存放的位置。但是,該函數并不能檢測緩沖區的大小。若調用者提供了一個指向堆棧的指針,并且gets()函數讀入的字符串數量超過了緩沖區的大小,該函數會將多出來的字符串繼續寫入堆棧中,從而覆蓋了堆棧中原始內容(緩沖區溢出攻擊)。
main () {char buffer[512]; // 在程序堆棧上申請并分配512個字符空間// ... ...gets(buffer); // 病毒執行入口,可將惡意代碼通過溢出覆蓋堆棧中原始數據 }?
文件結束符:EOF
EOF是在stdio.h文件中定義的常量,值為-1。
fputc函數返回值:執行成功返回值就是輸出的字符;失敗則返回EOF。
fgetc函數讀字符時遇到文件結束符,返回文件結束符EOF。
若從磁盤文件中順序讀取字符并在屏幕上顯示:
ch = fgetc(fp); while (ch != EOF) {putchar(ch);ch = fgetc(fp); }EOF是控制字符,不能在屏幕上顯示。由于ASCII編碼中不可能出現-1,因此EOF這樣定義是合適的。當讀入的字符值為-1時,表示讀入的已經不是正常的ASCII字符了,這樣就可以將-1作為文件結束符。
但這種情況只適用于讀取文本文件,目前ASCII已經允許使用緩沖文件系統處理二進制文件,而讀入某個字節中的二進制數據時有可能是-1。這樣就出現了讀取數據卻提前結束的情況。
正確的做法是我們要使用feof()函數來測試文件的當前狀態是否已經結束。
int feof (FILE * stream); _Check_return_ _CRTIMP int __cdecl feof(_In_ FILE * _File); ch = fgetc(fp); while (!feof(fp)) {putchar(ch);ch = fgetc(fp); }?
參考鏈接:
http://www.cnblogs.com/duzouzhe/archive/2009/10/24/1589348.html
http://www.jb51.net/article/37688.htm
http://www.blogjava.net/tinysun/archive/2010/07/26/327155.html
轉載于:https://www.cnblogs.com/yooyoo/p/4717924.html
總結
- 上一篇: python学习笔记(字典)
- 下一篇: 指针使用示例程序