C/C++檔案操作,資料處理
阿新 • • 發佈:2019-01-05
這幾天工作的過程中,常常要對TXT中的資料進行處理、分析。以前在學校時,對檔案操作、檔案內容處理的這部分知識用的不是很多,這幾天用這些知識的時候,總是不太熟悉,要不停查閱資料。因此,這裡總結一下,方便後期查閱。
在ANSI C中,對檔案的操作分為兩種方式,即流式檔案操作和I/O 檔案操作,這裡我們只介紹流式檔案操作。
(1)FILE進行檔案操作時,必須在程式一開始就先定義檔案指標:FILE *指標型別變數。FILE 在stdio.h中定義如下:
(2)fopentypedef struct { int level; unsigned flags; char fd; unsigned char hold; int bsize; unsigned char _FAR *buffer; unsigned char _FAR *curp; unsigned istemp; short token; } FILE;
FILE *fopen(const char *filename,const char *mode);
"r"(只讀) 為輸入開啟一個文字檔案。若指定的檔案不存在,則會出錯。"w"(只寫) 為輸出開啟一個文字檔案。若檔案不存在,系統將用指定名建立一個新檔案;若檔案已經存在,則將從起始位置重新寫,原有內容被更新
"rb"(只讀) 為輸入開啟一個二進位制檔案。功能與"r"相同。
"wb"(只寫) 為輸出開啟一個二進位制檔案。功能與"w"相同。
"a"(追加) 為追加資料開啟一個文字檔案。若檔案不存在,系統將用指定名建立一個新檔案;若檔案已經存在,則新資料寫在
"ab"(追加) 為追加資料開啟一個二進位制檔案。其餘功能與"a"相同。
"r+"(讀寫) 為讀/寫開啟一個已存在文字檔案。既可讀,也可寫,讀寫總是從檔案的起始位置開始;更換讀寫操作時不必關閉檔案。
"rb+"(讀寫) 為讀/寫開啟一個已存在的二進位制檔案。功能與"r+"相同。可由位置函式設定讀寫的起始位置。
"w+"(讀寫) 為讀/寫建立一個新的文字檔案。若檔案已存在,原有內容將被更新。
"wb+"(讀寫) 為讀/寫建立一個新的二進位制檔案。功能與"w+"相同;可由位置函式設定讀寫起始位置。
"a+"(讀寫) 為讀/寫開啟一個文字檔案。功能與"a"相同,只是在檔案尾部新增新資料後,可以從頭開始讀。
"ab+"(讀寫) 為讀/寫開啟一個二進位制檔案。功能與"a+"相同,只是在檔案尾部新增新資料之後,可由位置 函式設定開始讀的起始位置。
此函式返回一個FILE 指標,所以申明一個FILE 指標後不用初始化,而是用fopen()來返回一個指標並與一個特定的檔案相連,如果成敗,返回NULL。
FILE *fp;
if( fp=fopen("A.TXT","r") == NULL)
{
printf("can't find this file!/n");
exit(0);
}
(3)fgetcint fgetc(FILE *stream);
從檔案指標stream指向的檔案中讀取一個字元,讀取一個位元組後,游標位置後移一個位元組。這個函式的返回值,是返回所讀取的一個位元組。如果讀到檔案末尾或者讀取出錯時返回EOF。用法如下:char ch1=fgetc(fp);
(4)fgetschar *fgets(char *buf, int bufsize, FILE *stream);
*buf: 字元型指標,指向用來儲存所得資料的地址。bufsize: 整型資料,指明buf指向的字元陣列的大小。
*stream: 檔案結構體指標,將要讀取的檔案流。
從檔案結構體指標stream中讀取資料,每次讀取一行。讀取的資料儲存在buf指向的字元陣列中,每次最多讀取bufsize-1個字元(第bufsize個字元賦'\0'),如果檔案中的該行,不足bufsize個字元,則讀完該行就結束。函式成功將返回buf,失敗或讀到檔案結尾返回NULL。因此我們不能直接通過fgets的返回值來判斷函式是否是出錯而終止的,應該藉助feof函式或者ferror函式來判斷。
例:如果一個檔案的當前位置的文字如下:
Love, I Have
Since you can do it.
如果用fgets(str1,6,file1);去讀取,則執行後str1 = "Love," ,讀取了6-1=5個字元,這個時候再執行fgets(str1,20,file1)則執行後str1 = " I Have\n"。而如果fgets(str1,23,file1);
則執行str1="Love ,I Have",讀取了一行(包括行尾的'\n',並自動加上字串結束符'\0'),當前檔案位置移至下一行,雖然23大於當前行上字元總和,可是不會繼續到下一行。而下一次呼叫fgets()繼續讀取的時候是從下一行開始讀。
(5)fscanf
int fscanf(FILE *stream, char *format,[argument...]);
FILE *stream:檔案指標;char *format:格式字串(檢視其他資料,包括輸入格式、忽略元素、包含元素等);[argument...]:輸入列表。從一個流、檔案(stream)中讀入資料,執行格式化輸入,然後將結果按照格式儲存在列表中(可以理解為:將TXT檔案中的內容,有針對性地提取出來,並儲存在特定的列表、陣列中),fscanf遇到空格和換行時結束,注意空格時也結束。這與fgets有區別,fgets遇到空格不結束。
FILE *fp = 0;
char tmp[255] = {0};
fp = fopen(argv[1],"r+");
while(EOF != fscanf(fp,"%*[^','],\"%*[^','],%[^','],%*s",tmp))
{
sscanf(tmp,"\"%s\"",tmp1);
printf("%d\n",atoi(tmp1));
}
(6)fprintf int fprintf(FILE *stream,char *format,[argument]);
printf是標準輸出流的輸出函式,用來向螢幕這樣的標準輸出裝置輸出,而fprintf則是向檔案輸出,將輸出的內容輸出到硬碟上的檔案或是相當於檔案的裝置上。根據指定的format(格式)傳送資訊(引數)到由stream(流)指定的檔案. fprintf()只能和printf()一樣工作. fprintf()的返回值是輸出的字元數,發生錯誤時返回一個負值.char s[] = "this is a string";
char c = '\n';
stream = fopen( "fprintf.out", "w" );
fprintf( stream, "%s%c", s, c );
fprintf( stream, "%d\n", i );
fprintf( stream, "%f\n", fp );
(7)fwrite
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
buffer:是一個指標,對fwrite來說,是要獲取資料的地址;size:要寫入內容的單位元組數;count:要進行寫入size位元組的資料項的個數;stream:目標檔案指標;返回實際寫入的資料項個數count。向檔案寫入一個數據塊,這個函式以二進位制形式對檔案進行操作,不侷限於文字檔案。 FILE *stream;
struct mystruct s;
if ((stream = fopen("TEST.$$$", "wb")) == NULL) /* open file TEST.$$$ */
{
fprintf(stderr, "Cannot open output file.\n");
return 1;
}
s.i = 0;
s.cha = 'A';
fwrite(&s, sizeof(s), 1, stream); /* 寫的struct檔案*/
(8)sscanfint sscanf(const char *buffer,const char *format,[argument ]...);
fscanf是從檔案中讀,sscanf是從字串中讀,scanf是從鍵盤輸入中讀。sscanf會從buffer(一般為字元型陣列、字串)裡讀進資料,依照format的格式將資料寫入到argument(一般為字元型陣列)裡。sscanf("123456abcdedfBCDEF","%[1-9A-Z]",buf);
sscanf("iios/[email protected]", "%*[^/]/%[^@]", buf);
printf("%s\n", buf);
(9)getlinessize_t getline(char **lineptr, size_t *n, FILE *stream);
lineptr:指向存放該行字元的指標,如果是NULL,則有系統幫助malloc,請在使用完成後free釋放。n:如果是由系統malloc的指標,請填0。stream:檔案描述符。getline()函式會生成一個包含一串從輸入流讀入的字元的字串,直到一下情況發生會導致生成的此字串結束。1)到檔案結束,2)遇到函式的定界符,3)輸入達到最大限度。FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t read;
if(!(fp=fopen("1.txt","r")))
{
printf("\nerror on open 1.txt file!\n");
exit(1);
}
while ((read = getline(&line, &len, fp)) != -1);