教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

c/c++培訓(xùn)C語言核心知識總結(jié)(九)

更新時間:2016年10月21日16時41分 來源:傳智播客C++培訓(xùn)學(xué)院 瀏覽次數(shù):

九、文件操作;
 
數(shù)據(jù)I/O流
 
#include <stdio.h>
 
1 fopen()函數(shù):打開文件
函數(shù)原型:FILE *fopen(char restrict *filename, char restrict *mode);
// restrict C99標(biāo)準(zhǔn)才引進(jìn)的,屬于類型修飾符,表示修飾的這塊內(nèi)存空間只能被這個指針引用和修改,除此之外別無他法。
 
參數(shù):
filename: 需要打開的文件
mode: 文件打開方式
 
r 以只讀的方式打開文件,前提是這個文件必須存在(只寫 r 默認(rèn)是文本文件)
r+ 以可讀可寫的方式打開文件,前提是這個文件必須存在(默認(rèn)是文本文件)。
rb 以只讀的方式打開一個二進(jìn)制文件,前提是這個文件必須存在。
rb+ 以可讀可寫的方式打開一個二進(jìn)制文件,前提是這個文件必須存在。
 
w 以只寫的方式打開文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則清空內(nèi)容。
w+ 以可讀可寫的方式打開文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則清空內(nèi)容。
wb 以只寫的方式打開一個二進(jìn)制文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則清空內(nèi)容。
wb+ 以可讀可寫的方式打開一個二進(jìn)制文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則清空內(nèi)容。
 
a 以追加的方式打開只寫文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則在文件尾部追加內(nèi)容。
a+ 以追加的方式打開一個可讀可寫的文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則在文件尾部追加內(nèi)容。
ab 以追加的方式打開一個二進(jìn)制只寫文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則在文件尾部追加內(nèi)容。
ab+ 以追加的方式打開一個二進(jìn)制可讀可寫文件,如果這個文件不存在,就創(chuàng)建這個文件;如果這個文件存在,則在文件尾部追加內(nèi)容。
 
 
r(read): 讀;
w(write):寫;
a(append):追加;
+(plus):讀或?qū)?,主要是配合r、w、a使用;
t(text):文本文件;
b(binary):二進(jìn)制文件
 
返回值:如果文件順利打開,則返回值是指向這個文件流的文件指針,
如果文件打開失敗,返回 NULL (void*)0
 
一般來說,文件打開失敗會做一個文件指針錯誤判斷
FILE *fp = fopen("c:\\code\\text.c", "w+");
if(NULL == fp)
{
//code
//exit(-1);
}
 
2 fgetc(); 和 fputc();
1) fgetc() 文件字符讀取函數(shù)
原型: int fgetc(FILE * stream);
參數(shù): stream: 文件流
返回值: 成功返回獲取的字符ASCII碼,失敗返回 EOF(-1);
舉例:
char ch = fgetc(fp); // 從fp指向的文件流里接收文件流里的第一個字符
 
 
2) fputc() 文件字符寫入函數(shù)
原型: int fputc(int ch, FILE * stream);
參數(shù): ch :就是寫入的字符,函數(shù)在執(zhí)行的時候,會自動把 ch ASCII碼 轉(zhuǎn)換成一個 unsigned char 類型。
stream: 文件流
返回值: 成功返回輸出的字符,失敗返回 EOF(-1);
舉例:
fputc(ch, fp); // 把字符ch寫入到 fp 所指向的文件流里。
 
3 fgets(); 和 fputs();
1) fgets() 讀取文件字符串函數(shù)
原型:char *fgets(char *str, int size, FILE* fp);
參數(shù): str : 保存從fp指向的文件流里讀取的一行字符串。
size: 從文件流里讀取的字符串不超過 size 個字符。( 一般會使用size - 1,留一個字符位置給 '\0')
fp : 文件指針
返回值:成功返回讀取的字符串所在的內(nèi)存首地址,失敗返回 NULL(0);
舉例:
char str[20] = { 0 };
fgets(str, 20 - 1, fp); // 從fp指向的文件流的第一行里讀取 19個字符,然后放到字符數(shù)組 str里。
 
2) fputs() 寫入文件字符串函數(shù)
原型:int fputs(char *str, FILE* fp);
參數(shù): str: 要寫入到文件里字符串(不包括'\0')
fp: 文件指針,成功寫入一個字符串后,文件指針會自動后移
返回值:成功為寫入的字符個數(shù),失敗則返回 EOF(-1)。
舉例:
char str[20] = "Hello Kitty!";
fputs(str, fp); // 向 fp 指向的文件流里寫入一個字符串 str,具體怎么寫,看 mode 屬性。
 
4 fprintf(); 和 fscanf();
1) fprintf() 將格式化后的數(shù)據(jù)寫入到文件流里
原型: int fprintf(FILE *stream, char *format, argument...);
舉例:
int i = 10;
float f = 3.14;
char ch = 'C';
char str[10] = "haha";
fprintf(fp, "%d %f %c %s\n", i, f, ch, str); // 將各個數(shù)據(jù)按格式寫入到文件流里
 
2) fscanf() 從文件流里獲取數(shù)據(jù)格式化寫入輸入流里
原型: int fscanf(FILE *stream, char *format, argument... );
舉例:
int i;
float f;
char ch;
char str[10];
fscanf(fp, "%d,%f", &i, &f);
// 如果不需要從文件里面寫入字符串,那么就可以用逗號或者其他符號來分隔
 
fscanf(fp, "%s%c", str, &ch);
// 如果文件里需要寫入字符串,那么字符串與其他數(shù)據(jù)之間只能用空格和回車來分隔
 
 
5 fread(); 和 fwrite(); 二進(jìn)制文件讀寫函數(shù)
函數(shù)原型:
size_t fread(void *ptr, size_t size, size_t count, FILE* fp);
size_t fwrite(void *ptr, size_t size, size_t count, FILE* fp);
參數(shù): ptr: 是一個指針,對應(yīng) fread()來說,是從文件里讀入的數(shù)據(jù)存放的地址;
 對應(yīng) fwrite()來說,是寫入到文件里的數(shù)據(jù)存放的地址。
size: 每次要讀寫的字節(jié)數(shù)
count : 讀寫的次數(shù)
fp: 文件指針
 
返回值: 成功讀取/寫入的字節(jié)數(shù)
 
舉例:
char str[] = { 0 };
fread(str, sizeof(char) * 10, 1, fp);
// 每次從fp指向的文件中讀取10個字節(jié)大小,放入字符數(shù)組 str 中,總共讀1次
fwrite(str, sizeof(char) * 10, 1, fp);
// 每次從str里獲取 10個字節(jié)大小,寫入到 fp 指向的文件中,總共寫1次
 
 
6 fseek(); 文件指針操作函數(shù)
函數(shù)原型: size_t fseek(FILE* fp, long offset, int whence);
參數(shù): fp : 文件指針
offset:  偏移量,基于起始點偏移了 offset 個字節(jié)
whence : 起始點(三個):
SEEK_SET 0 文件開頭位置
SEEK_CUR 1 當(dāng)前位置
SEEK_END 2 文件結(jié)尾位置
 
舉例
 fseek(fp, 0, SEEK_END);
 // 將文件指針指向文件結(jié)尾,并偏移了 0 個字節(jié),也就是直接將文件指針指向文件結(jié)尾
 fseek(fp, -10, SEEK_CUR);
 // 將文件指針指向當(dāng)前位置,并偏移了 -10 個字節(jié),也就是將文件指針往前移動10個字節(jié)
 
7 ftell(); 文件指針操作函數(shù)
函數(shù)原型:  long ftell(FILE* fp);
參數(shù): fp  文件指針
返回值:返回文件指針當(dāng)前位置,基于文件開頭的偏移字節(jié)數(shù),
 
舉例: long len = ftell(fp);
// 返回文件指針當(dāng)前位置,基于文件開頭的偏移字節(jié)數(shù),保存到 len 里。
 
8 rewind(); 文件指針操作函數(shù)
函數(shù)原型: void rewind(FILE* stream);
參數(shù): fp 文件指針
 
舉例: rewind(fp);
// 將文件指針重新指向I/O流(文件流)的開頭。
 
stream > istream / ostream -> fstream -> sstream
 
6\7\8 大例子
 
FILE *fp = fopen("C:\\code\\a.txt", "r+");
fseek(fp, 0, SEEK_END); // 將文件指針指向文件結(jié)尾
long len = ftell(fp); // 獲取文件指針位置,得到文件的大小(Byte)
rewind(fp); // 將文件指針重新指向文件開頭
 
9 fflush(); 清空數(shù)據(jù)流里的數(shù)據(jù)
 
函數(shù)原型:  void fflush(FILE* stream);
參數(shù): stream 數(shù)據(jù)流
 
舉例:
fflush(fp); // 清空文件流
fflush(stdin); // 清空輸入流
fflush(stdout); // 清空輸出流
 
 
10 int stat(const char *path, struct stat *buf);
// 自行補(bǔ)充
 
 
11 rename(); 和 remove();
 
rename(FILE* filename1, FILE* filename2);
rename("old_name.txt", "new_name.txt");
// 把old_name.txt 重命名為 new_name.txt
 
remove(FILE* filename);
remove("C:\\code\\a.txt");
// 將 絕對路徑下的 a.txt 文件刪除
 
12 feof();
原型: int feof(FILE* fp);
參數(shù): fp  文件指針
返回值: 一旦文件指針指向文件結(jié)尾,就返回一個真值;否則返回非真值(0)
 
1. 這個函數(shù)達(dá)到文件結(jié)尾的時候,返回的是一個真值,所以在做判斷的時候要注意 !feof(fp)
2. 這個函數(shù)必須對文件進(jìn)行過一次讀寫操作才會生效,也就是說哪怕這個文件是空的,也必須讀寫一次,feof()才會返回真值。
文件結(jié)束是一個標(biāo)識符,每次對文件讀寫都會修改這個標(biāo)識符的位置,對文件讀寫一次,文件標(biāo)識符才會被找到,feof()做出返回操作。
 
13 fclose();
原型: int flcose(FILE* fp);
參數(shù): fp 文件指針
返回值: 如果成功釋放,返回 0, 否則返回 EOF(-1);
 
fclose(fp); 表示釋放文件指針和相關(guān)的文件緩沖區(qū),文件指針不再合法指向那塊區(qū)域,但是不代表清空對應(yīng)的區(qū)域。

 
 
UTF-8 編碼格式下 一個漢字 3 個字節(jié)
GBK 編碼格式下 一個漢字 2 個字節(jié)
 
// UTF-8 下 漢字逆置原理
#include <stdio.h>
#include <string.h>
 
int main(void)
{
char str[] = "阿基米德";
int len = strlen(str);
 
// printf("%c%c\n", str[0], str[1]); // 打印"阿"
 
for (int i = len - 1; i > 0; i -= 3) // UTF-8 編碼下是3個字節(jié),GBK下是2個字節(jié)
{
printf("%c%c\n", str[i - 1], str[i]);
}
 
 
return 0;
}
 
不同操作系統(tǒng)的行尾標(biāo)志:
CR LF \ CR \ LF
 
CR 是 '\r' 回車
LF 是 '\n' 換行
 
在DOS和NT內(nèi)核的Windows下,采用的是 回車+換行(CR LF '\r''\n') 來表示下一行的開始
在Unix/Linux下,采用的是 換行(LF '\n') 來表示下一行的開始
在Macintosh下(OS X) ,采用的是 回車(CR '\r') 來表示下一行的開始
本文版權(quán)歸傳智播客C++培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:傳智播客C/C++培訓(xùn)學(xué)院
首發(fā):http://www.xamj520.com/c/ 
0 分享到:
和我們在線交談!