日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言再学习 -- 文件

發布時間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言再学习 -- 文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文件是什么

一個文件(file)通常就是磁盤上的一段命名的存儲區。C 將文件看成是連續的字節序列,其中每一個字節都可以單獨地讀取。

二進制和文本模式
1、在windows系統中,文本模式下,文件以"\r\n"代表換行。若以文本模式打開文件,并用fputs等函數寫入換行符"\n"時,函數會自動在"\n"前面加上"\r"。即實際寫入文件的是"\r\n" 。

2、在類Unix/Linux系統中文本模式下,文件以"\n"代表換行。所以Linux系統中在文本模式和二進制模式下并無區別。

標準文件

C 程序自動打開3個文件。這3個文件被稱為標準輸入,標準輸出和標準錯誤輸出。默認的標準輸入是系統的一般輸入設備,通常為鍵盤;默認的標準輸出和標準錯誤輸出是系統的一般輸出設備,通常為顯示器,分別得到文件描述符 0, 1, 2.

下面的方法從標準輸入(鍵盤)獲得一個字符: ?ch = getchar ( );

標準文件指針:

stdio.h文件把3個文件指針與3個C 程序自動打開的標準文件進行了并聯,如下表所示:

標準文件 ?

文件指針 ?

一般使用的設備 ?

標準輸入

stdin

鍵盤

標準輸出

stdout

顯示器

標準錯誤

stderr

顯示器

這些指針都是FILE指針類型,所以可以被用作標準I/O函數的參數。


stdout和stderr比較:

stderr -- 標準錯誤輸出設備
stdout -- 標準輸出設備 (printf("..")) 同 stdout。
兩者默認向屏幕輸出。但如果用轉向標準輸出到磁盤文件,則可看出兩者區別。stdout輸出到磁盤文件,stderr在屏幕,例如:
fprintf(stderr, "Can't open it!\n");
fprintf(stdout, "Can't open it!\n");
在my.exe
Can't open it!
Can't open it!
Can't open it!

轉向標準輸出到磁盤文件tmp.txt
my.exe > tmp.txt
Can't open it!

用TYPE 看 tmp.txt的內容:
TYPE tmp.txt
Can't open it!
Can't open it!


stderr是不緩存的,stdout是行間緩存的。請注意:
for(i = 0; i < 10; i++)
? ? {
? ? ? fprintf(stdout, "This is stdout[%d]", i);
? ? ? fprintf(stderr, "This is stderr[%d]", i);
? ? }
會全部顯示stderr之后,再顯示stdout。又因為stdout是行內緩存,所以加 \n 后會立刻顯示。


文件操作分成如下三個步驟:

1、打開文件 (fopen)

2、操作文件 (fread/fwrite)

3、關閉文件 (fclose)

下面來一一介紹:

打開文件 -- fopen ( )函數:

函數原型:
FILE * fopen(const char * path,const char * mode);

返回值:

文件順利打開后,指向該流的文件指針就會被返回。如果文件打開失敗則返回NULL,并把錯誤代碼存在errno中。
一般而言,打開文件后會做一些文件讀取或寫入的動作,若打開文件失敗,接下來的讀寫動作也無法順利進行,所以一般在fopen()后作錯誤判斷及處理

參數說明:

path:字符串包含欲打開的文件路徑及文件名

mode:C 字符串,包含了文件訪問模式,模式如下:

模式字符串

?

“r”

以只讀方式打開文件,該文件必須存在

“r+”

以只讀寫方式打開文件,該文件必須存在

“w”

打開只寫文件,若文件存在則文件長度清零,即該文件內容會消失。

若文件不存在則建立該文件

“w+”

打開可讀寫文件,若文件存在則文件長度清零,即該文件內容會消失。

若文件不存在則建立該文件。

“a”

以附加的方式打開只寫文件。若文件不存在,則會建立該文件,如果文件存在,

寫入的數據會被加到文件尾,即文件原先的內容會被保留。(EOF符保留)

“a+”

以附加方式打開可讀寫的文件。若文件不存在,則會建立文件,如果文件存在,

寫入的數據會被加到文件尾后,即文件原先的內容會被保留。(原來的EOF符不保留)

“rb”, “wb”, “ab”, “ab+”, “a+b”,

?“wb+”, “w+b”, “ab+”, “a+b”

與前面的模式相似,只是使用二進制模式而非文本模式打開文件


關閉文件 -- fclose ( )函數:

函數原型:

int fclose( FILE *fp );

返回值:
如果流成功關閉,fclose 返回 0,否則返回EOF(-1)。(如果流為NULL,而且程序可以繼續執行,fclose設定error number給EINVAL,并返回EOF。)

因此,可在fclose(fp)后使用
if(fclose())
{
? ? perror("fclose");
}
來判斷是否成功關閉文件,關閉失敗,則fclose返回“1”并輸出出錯原因。

擴展:C語言再學習 -- EOF與feof函數

[cpp]?view plaincopy
  • 示例一:??
  • #include<stdio.h>??
  • int?main(void)??
  • {??
  • ????FILE*fp?=?NULL;??
  • ????fp?=?fopen("abc.txt",?"r");??
  • ????if(NULL?==?fp)??
  • ????{??
  • ????perror("error...");??
  • ????????exit?(1);??
  • ????}??
  • ????fclose?(fp);??
  • ????fp?=?NULL;??
  • ?????return?0;??
  • }??

  • 在文件操作時,需要注意以下幾點問題
    1、在定義文件指針時,要將文件指針指向空;如 FILE *fp = NULL;
    2、需要判斷文件是否打開成功,如 if(NULL == fp)
    3、文件操作完成后,注意要將文件關閉,否則會造成文件所占用內存泄露和在下次訪問文件時出現問題。
    4、文件關閉后,需要將文件指針指向空,這樣做會防止出現游離指針,而對整個工程造成不必要的麻煩;如:fp = NULL;

    [cpp]?view plaincopy
  • //?一個簡單的文件壓縮程序??
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<string.h>??
  • ??
  • #define?LEN?40??
  • int?main?(int?argc,?char?*argv[])??
  • {??
  • ????FILE?*in,?*out;??
  • ????int?ch;??
  • ????char?name[LEN];??
  • ????int?count?=?0;??
  • ??
  • ????if?(argc?<?2)??
  • ????{??
  • ????????fprintf?(stderr,?"Usage:?%s?filename\n",?argv[0]);??
  • ????????exit?(1);??
  • ????}??
  • ????if?((in?=?fopen?(argv[1],?"r"))?==?NULL)??
  • ????{??
  • ????????fprintf?(stderr,?"I?couldn't?open?the?file?\"s\"\n",?argv[1]);??
  • ????????exit?(2);??
  • ????}??
  • ??
  • ????strcpy?(name,?argv[1]);??
  • ????strcat?(name,?".red");??
  • ????if?((out?=?fopen?(name,?"w"))?==?NULL)??
  • ????{??
  • ????????fprintf?(stderr,?"Can't?Create?output?file.\n");??
  • ????????exit?(3);??
  • ????}??
  • ????while?((ch?=?getc?(in))?!=?EOF)??
  • ????????if?(count++?%?3?==?0)??
  • ????????????putc?(ch,?out);??
  • ????if?(fclose?(in)?!=?0?||?fclose?(out)?!=?0)??
  • ????????fprintf?(stderr,?"Error?in?closing?files\n");??
  • ????return?0;??
  • }??
  • ??
  • 同一目錄下創建文件eddy,里面添加內容?So?even?Eddy?came?oven?ready?.??
  • 輸出結果:創建?eddy.red??
  • Send?money??

  • 操作文件 -- fread ( )函數和fwrite ( )函數

    fwrite ( )函數

    函數功能:
    指向文件寫入一個數據塊。
    函數原型:
    size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);
    注意:這個函數以二進制形式對文件進行操作,不局限于文本文件
    參數:
    (1)buffer:是一個指針,對fwrite來說,是要獲取數據的地址;
    (2)size:要寫入內容的單字節數;(size_t是sizeof返回的類型,通常是unsigned int類型)
    (3)count:要進行寫入size字節的數據項的個數;
    (4)stream:目標文件指針;
    返回值:
    返回實際寫入的數據塊數目 count。


    fread ( )函數:

    函數原型
    size_t fread ( void *buffer, size_t size, size_t count, FILE *stream);
    參數:
    (1)buffer:用于接收數據的內存地址
    (2)size:要讀的每個數據項的字節數,單位是字節?(size_t是sizeof返回的類型,通常是unsigned int類型)
    (3)count:要讀count個數據項,每個數據項size個字節.
    (4)stream:輸入流
    返回值:
    返回真實寫入的項數,若大于count則意味著產生了錯誤。另外,產生錯誤后,文件位置指示器是無法確定的。若其他stream或buffer為空指針,或在unicode模式中寫入的字節數為奇數,此函數設置errno為EINVAL以及返回0.
    函數功能:
    從一個文件流中讀數據,最多讀取count個項,每個項size個字節,如果調用成功返回實際讀取到的項個數(小于或等于count),如果不成功或讀到文件末尾返回 0。

    [cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<string.h>??
  • int?main()??
  • {??
  • ???FILE?*fp;??
  • ???char?c[]?=?"This?is?w3cschool";??
  • ???char?buffer[20];??
  • ??
  • ???/*?打開文件用于讀寫?*/??
  • ???fp?=?fopen("file.txt",?"w+");??
  • ??
  • ???/*?寫入數據到文件?*/??
  • ???fwrite(c,?strlen(c)?+?1,?1,?fp);??
  • ??
  • ???/*?查找文件的開頭?*/??
  • ???fseek(fp,?SEEK_SET,?0);??
  • ??
  • ???/*?讀取并顯示數據?*/??
  • ???fread(buffer,?strlen(c)+1,?1,?fp);??
  • ???printf("%s\n",?buffer);??
  • ???fclose(fp);??
  • ???return(0);??
  • }??

  • 隨機存取:fseek ( )、ftell ( )、rewind ( )

    fseek ( )函數

    函數功能:

    重定位流(數據流/文件)上的文件內部位置指針

    注意:文件指針指向文件/流。位置指針指向文件內部的字節位置,隨著文件的讀取會移動,文件指針如果不重新賦值將不會改變或指向別的文件。

    函數原型:

    int fseek(FILE *stream, long offset, int fromwhere);

    參數:

    (1)stream:為文件指針
    (2)offset:為偏移量,正數表示正向偏移,負數表示負向偏移(數字值用3L、10L等,L后綴表示long類型)
    (3)origin:設定從文件的哪里開始偏移,可能取值為:SEEK_CUR、 SEEK_END 或 SEEK_SET
    SEEK_SET: 文件開頭
    SEEK_CUR: 當前位置
    SEEK_END: 文件結尾
    其中SEEK_SET,SEEK_CUR和SEEK_END依次為0,1和2.

    返回值:

    成功,返回 0,失敗返回 -1,并設置error的值,可以用perror()函數輸出錯誤。

    函數描述:

    函數設置文件指針stream的位置。如果執行成功,stream將指向以fromwhere(偏移起始位置:文件頭0(SEEK_SET),當前位置1(SEEK_CUR),文件尾2(SEEK_END))為基準,偏移offset(指針偏移量)個字節的位置。如果執行失敗(比如offset超過文件自身大小),則不改變stream指向的位置。

    上面這句話意思是,函數執行之后,文件指針就移動到了fromwhere + offset位置處,如果offset超過文件自身大小,則不改變stream指向的位置。

    fseek函數和lseek函數類似,但lseek返回的是一個off_t數值,而fseek返回的是一個整型.

    #include <stdio.h> int main (void) {char ch = 0;FILE *fp = fopen ("abc.txt", "r");if (fp){//ABCDEFGHIGKLMNfseek (fp, 2L, SEEK_SET); //文件開頭 (ABC)//(2+0 = 2 文件指針移動到2的位置)fread (&ch,sizeof (char), 1, fp);printf ("%c\n", ch);fseek (fp, 3L, SEEK_CUR); //當前位置 (CDEFG)//(3+1 = 4 文件指針移動到4的位置)fread (&ch,sizeof (char), 1, fp); printf ("%c\n", ch);fseek (fp, -3L, SEEK_END); //文件結尾 MN) //(-3+2 = -1 文件指針移動到-1位置)fread (&ch,sizeof (char), 1, fp); printf ("%c\n", ch);fclose (fp); fp = NULL;} return 0; } 輸出結果: C G M

    ftell ()函數

    函數原型:

    long ftell(FILE *stream);

    函數功能:
    函數 ftell() 用于得到文件位置指針當前位置相對于文件首的偏移字節數。在隨機方式存取文件時,由于文件位置頻繁的前后移動,程序不容易確定文件的當前位置。使用fseek函數后再調用函數ftell()就能非常容易地確定文件的當前位置。

    返回值:

    以一個long類型值返回一個文件的當前位置。如果發生錯誤,則返回 -1L,全局變量 errno 被設置為一個正值。

    調用示例編輯:
    ftell(fp);利用函數 ftell() 也能方便地知道一個文件的長。如以下語句序列: fseek(fp, 0L,SEEK_END); len =ftell(fp); 首先將文件的當前位置移到文件的末尾,然后調用函數ftell()獲得當前位置相對于文件首的位移,該位移值等于文件所含字節數。

    #include <stdio.h> int main (void) {FILE *fp;int len;//ABCDEFfp = fopen ("abc.txt", "r");if (fp == NULL){perror ("error");return -1;}fseek (fp, 0, SEEK_END);len = ftell (fp);fclose (fp);printf ("abc.txt 的總大小 = %d 字節\n", len);return 0; }輸出結果: abc.txt 的總大小 = 8 字節


    rewind ()函數:

    函數原型:
    void rewind(FILE *stream)
    返回值:
    該函數不返回任何值。
    函數功能:?
    將文件內部的位置指針重新指向一個流(數據流/文件)的開頭
    注意:不是文件指針而是文件內部的位置指針,隨著對文件的讀寫文件的位置指針(指向當前讀寫字節)向后移動。而文件指針是指向整個文件,如果不重新賦值文件指針不會改變。
    rewind函數作用等同于 (void)fseek(stream, 0L, SEEK_SET);[1]?

    #include <stdio.h>int main() {char str[] = "Hello World!";FILE *fp;int ch;/* 首先讓我們在文件中寫入一些內容 */fp = fopen( "file.txt" , "w" );fwrite(str , 1 , sizeof(str) , fp );fclose(fp);fp = fopen( "file.txt" , "r" );while(1){ch = fgetc(fp);if( feof(fp) ){break ;}printf("%c", ch);}rewind(fp); //從頭從新開始打印printf("\n");while(1){ch = fgetc(fp);if( feof(fp) ){break ;}printf("%c", ch);}printf ("\n");fclose(fp);return(0); } 輸出結果: Hello World! Hello World!



    總結

    以上是生活随笔為你收集整理的C语言再学习 -- 文件的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。