欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言文件操作的入門詳解教程

 更新時(shí)間:2021年04月01日 11:18:37   作者:guguguhuha  
這篇文章主要給大家介紹了關(guān)于C語言文件操作的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一.一些需要掌握的知識(shí)點(diǎn)

  文件有千千萬萬,但是在我們的程序設(shè)計(jì)當(dāng)中,我們談的文件一般有兩種:

  1.程序文件

  包括源程序文件(后綴為.c),目標(biāo)文件(windows環(huán)境后綴為.obj),可執(zhí)行程序(windows環(huán)境后綴為.exe)。

  2.數(shù)據(jù)文件

  文件的內(nèi)容不一定是程序,而是程序運(yùn)行時(shí)讀寫的數(shù)據(jù),比如程序運(yùn)行需要從中讀取數(shù)據(jù)的文件,或者輸出內(nèi)容的文件。

  而在本節(jié)中,我們主要提到的是數(shù)據(jù)文件。

1.文件名

  我們知道,名字都是用來標(biāo)識(shí)和區(qū)別事物的,那么文件名也是這樣,是區(qū)別各個(gè)文件的標(biāo)識(shí)。

  一個(gè)文件名要包含 3 個(gè)部分:文件路徑+文件名主干+文件后綴

  如:C:\Windows\System32\drivers\etc.txt

  其中 :C:\Windows\System32\drivers\ 是文件路徑,etc 是文件名主干,txt 是文件名后綴。

  當(dāng)然了,各個(gè)平臺(tái)的文件路徑并不相同,以及為了方便起見文件標(biāo)識(shí)通常別稱為文件名

2.文件類型

  根據(jù)數(shù)據(jù)的組織形式,數(shù)據(jù)文件被稱為文本文件或者二進(jìn)制文件。

  二進(jìn)制文件:數(shù)據(jù)在內(nèi)存中以二進(jìn)制的形式存儲(chǔ),并不加轉(zhuǎn)換的輸出到外存。

  文本文件:要求在外存上以ASCII碼的形式存儲(chǔ),需要在存儲(chǔ)前轉(zhuǎn)換,以ASCII字符的形式存儲(chǔ)的文件。

  那么一個(gè)數(shù)據(jù)在內(nèi)存中是怎樣存儲(chǔ)的呢?

  字符一律以ASCII形式存儲(chǔ),數(shù)值型數(shù)據(jù)既可以用ASCII形式存儲(chǔ),也可以使用二進(jìn)制形式存儲(chǔ)。

  如有整數(shù)10000,如果以ASCII碼的形式輸出到磁盤,則磁盤中占用5個(gè)字節(jié)(每個(gè)字符一個(gè)字節(jié))

  而二進(jìn)制形式輸出,則在磁盤上只占4個(gè)字節(jié)(VS2019測(cè)試)。

如:

我們可以測(cè)試一番:

#include <stdio.h>
int main()
{
 int a = 10000;
 FILE* pf = fopen("test.txt", "wb");
 fwrite(&a, 4, 1, pf);//二進(jìn)制的形式寫到文件中
 fclose(pf);
 pf = NULL;
 return 0;
}

我們打開的時(shí)候要注意以二進(jìn)制編輯器來打開,你會(huì)發(fā)現(xiàn)出現(xiàn)了如下圖顯示的一串?dāng)?shù)字,其中它們是以十六進(jìn)制現(xiàn)實(shí)的,轉(zhuǎn)換一下,剛好是上圖顯示的那串二進(jìn)制數(shù)字(注意VS采用的是小端儲(chǔ)存模式)

3.數(shù)據(jù)流

  數(shù)據(jù)流:

  指程序于數(shù)據(jù)的交互是以流的形式進(jìn)行的,包括輸入流與輸出流;

  輸入流:

  程序從輸入流讀取數(shù)據(jù)源。數(shù)據(jù)源包括鍵盤,文件,網(wǎng)絡(luò)等,即:將數(shù)據(jù)源讀入到程序的外界通道。

  輸出流:

  程序向輸出流寫入數(shù)據(jù)。將程序中的數(shù)據(jù)輸出到外界(顯示器,打印機(jī),文件,網(wǎng)絡(luò),等)的通信通道。

  采用數(shù)據(jù)流的目的:使得輸入輸出獨(dú)立于設(shè)備,不關(guān)心數(shù)據(jù)源來自何方,也不管輸出的目的地是何種設(shè)備。

4.文件緩沖區(qū)

  緩沖區(qū):

  指在程序運(yùn)行時(shí),所提供的額外內(nèi)存,可用來暫時(shí)存放做準(zhǔn)備執(zhí)行的數(shù)據(jù)。它可在創(chuàng)建、訪問、刪除靜態(tài)數(shù)據(jù)上,大大提高運(yùn)行速度(速度的提高程度有時(shí)甚至可高達(dá)幾十倍),

  為我們提供了極大的便捷,節(jié)省了大量的時(shí)間與精力

  文件緩沖區(qū): 

  ANSIC 標(biāo)準(zhǔn)采用“緩沖文件系統(tǒng)”處理的數(shù)據(jù)文件的,所謂緩沖文件系統(tǒng)是指系統(tǒng)自動(dòng)地在內(nèi)存中為程序中每一個(gè)正在使用的文件開辟一塊“文件緩沖區(qū)”。

  從內(nèi)存向磁盤輸出數(shù)據(jù)會(huì)先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤上。如果從磁盤向計(jì)算機(jī)讀入數(shù)據(jù),則從磁盤文件中讀取數(shù)據(jù)輸入到內(nèi)存緩沖區(qū)(充滿緩沖區(qū)),

  然后再?gòu)木彌_區(qū)逐個(gè)地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)(程序變量等)。緩沖區(qū)的大小根據(jù)C編譯系統(tǒng)決定的。

如:

  無論是輸入輸出,都先在緩沖區(qū)里存著,然后在進(jìn)行輸入輸出。

5.文件指針

  緩沖文件系統(tǒng)中,關(guān)鍵的概念是“文件類型指針”,簡(jiǎn)稱“文件指針”。

  每個(gè)被使用的文件都在內(nèi)存中開辟了一個(gè)相應(yīng)的文件信息區(qū),用來存放文件的相關(guān)信息(如文件的名字,文件狀態(tài)及文件當(dāng)前的位置等)。

  這些信息是保存在一個(gè)結(jié)構(gòu)體變量中的。該結(jié)構(gòu)體類型是有系統(tǒng)聲明的,取名FILE。

  我們可以來看在VS 2019中FILE的聲明:

//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Stream I/O Declarations Required by this Header
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#ifndef _FILE_DEFINED
#define _FILE_DEFINED
typedef struct _iobuf
{
 void* _Placeholder;
} FILE;
#endif

  不同的C編譯器的FILE類型包含的內(nèi)容不完全相同,但是大同小異。

  每當(dāng)打開一個(gè)文件的時(shí)候,系統(tǒng)會(huì)根據(jù)文件的情況自動(dòng)創(chuàng)建一個(gè)FILE結(jié)構(gòu)的變量,并填充其中的信息,使用者不必關(guān)心細(xì)節(jié)。

  一般都是通過一個(gè)FILE的指針來維護(hù)這個(gè)FILE結(jié)構(gòu)的變量,這樣使用起來更加方便。

  如下:我們便創(chuàng)建了一個(gè)文件指針

FILE* pf;//文件指針變量

  定義pf是一個(gè)指向FILE類型數(shù)據(jù)的指針變量??梢允筽f指向某個(gè)文件的文件信息區(qū)(是一個(gè)結(jié)構(gòu)體變量)。

  通過該文件信息區(qū)中的信息就能夠訪問該文件。也就是說,通過文件指針變量能夠找到與它關(guān)聯(lián)的文件。

比如:

到此,我們的基本概念就結(jié)束了,下面進(jìn)入到函數(shù)部分:

二.與文件操作相關(guān)的一些函數(shù)

 1.文件的打開及關(guān)閉

  文件在使用前,我們肯定要打開文件;在使用結(jié)束后,我們需要關(guān)閉文件。

  1.fopen() --- 文件打開函數(shù)

  聲明:文檔

FILE* fopen(const char* filename, const char* mode);

  參數(shù):

  const char* filename ---- 文件名

  const char* mode ---- 文件打開方式

  文件打開方式:

那,接下來看一個(gè)實(shí)例:

/* fopen example */
#include <stdio.h>
int main()
{
 FILE* pFile;
 pFile = fopen("myfile.txt", "w");//打開一個(gè)文件(沒有就創(chuàng)建),以寫的方式打開
 if (pFile != NULL)//如果打開成功
 {
 fputs("fopen example", pFile);//就往文件里寫入 fopen example
 fclose(pFile);//關(guān)閉文件
 }
 return 0;
}

  2.fclose() --- 文件關(guān)閉函數(shù)

  聲明:文檔

int fclose(FILE* stream);

  參數(shù)為要關(guān)閉文件的文件指針

示例:

int main()
{
 //相對(duì)路徑
 //.. 表示上一級(jí)目錄
 //. 當(dāng)前目錄
 //FILE* pf = fopen("../data.txt", "r");//在上一級(jí)文件中打開data.txt,如果沒有就報(bào)錯(cuò)
 //絕對(duì)路徑 C:\Windows\System32\drivers\etc.txt
 //./hehe/test.txt
 //../../
 FILE* pf = fopen("../../data.txt", "r");
 if (pf == NULL)
 {
 printf("打開文件失敗\n");
 printf("%s\n", strerror(errno));//注意頭文件的包含 stding.h errno.h
 return 1;//失敗返回
 }
 //打開文件成功
 printf("打開文件成功\n");
 //讀寫文件
 //...

 //關(guān)閉文件
 fclose(pf);
 pf = NULL;//及時(shí)置NULL

 return 0;
}

注:

  其他的文件打開模式,將在函數(shù)講解的時(shí)候一并講解:

2.文件的順序讀寫

  1. 字符輸入輸出函數(shù)

   fput--- 向指定輸出流輸出一個(gè)字符聲明

int fputc ( int character, FILE * stream );

   參數(shù):

    int character --- 所輸入的字符

    FILE * stream --- 指定輸出流

  fgetc--- 向指定輸入流輸入一個(gè)字符聲明

int fgetc ( FILE * stream );

   參數(shù):

    FILE * stream --- 指定輸入流

示例 1:

//在文件里寫入a-z26個(gè)字母
int main()
{
 //fopen函數(shù)如果是以寫的形式打開
 //如果文件不錯(cuò)在,會(huì)創(chuàng)建這個(gè)文件
 //如果文件存在,會(huì)清空文件的內(nèi)容
 //fopen函數(shù)如果是以讀的形式打開
 //文件不存在打開失敗

 FILE* pf = fopen("data.txt", "w");
 if (pf == NULL)
 {
 printf("%s\n", strerror(errno));
 return 1;//失敗返回
 }
 //寫文件
 int i = 0;
 for (i = 'a'; i <= 'z'; i++)
 {
 fputc(i, pf);//在文件里寫 --- pf 我們自己定義的文件指針
 fputc(i, stdout);//顯示在屏幕上 --- stdout --- 標(biāo)準(zhǔn)輸出流
 } // 從鍵盤輸入 --- stdin --- 標(biāo)準(zhǔn)輸入流

 //關(guān)閉文件
 fclose(pf);
 pf = NULL;

 return 0;
}

這里需要注意的就是所指定的輸出流:

  在C語言所寫的程序運(yùn)行起來時(shí),會(huì)默認(rèn)打開三個(gè)流:

    1.stdin - 標(biāo)準(zhǔn)輸入流 (鍵盤)

    2.stdout - 標(biāo)準(zhǔn)輸出流 (屏幕)

    3.stderr - 標(biāo)準(zhǔn)錯(cuò)誤流(屏幕)

示例 2:

//從剛才寫的文件,再把內(nèi)容讀出來
int main()
{
 FILE* pf = fopen("data.txt", "r");// r 是以讀的形式打開文件,如果沒有該文件就報(bào)錯(cuò)
 if (pf == NULL)
 {
 printf("%s\n", strerror(errno));
 return 1;
 }
 //打開文件成功,讀文件
 //int ch = fgetc(pf);
 //printf("%c\n", ch);//a
 //ch = fgetc(pf);
 //printf("%c\n", ch);//b
 //ch = fgetc(pf);
 //printf("%c\n", ch);//c
 //ch = fgetc(pf);
 //printf("%c\n", ch);//d
 int ch = 0;
 while ((ch = fgetc(pf)) != EOF)// pf --- 所指定的輸入流
 {
 printf("%c ", ch);
 }

 //關(guān)閉文件
 fclose(pf);
 pf = NULL;
 return 0;
}

這里需要注意一點(diǎn):

  fgetc() 的返回值:我們?cè)谶@就只說出現(xiàn)錯(cuò)誤的信息:

    If the position indicator was at theend-of-file, the function returnsEOFand sets theeof indicator(feof) ofstream.
    If some other reading error happens, the function also returnsEOF, but sets itserror indicator(ferror) instead.

  翻譯過來就是:

    如果文件指針處于‎文件末端‎‎,則函數(shù)返回EOF,并設(shè)置‎‎流‎‎的‎‎eof指示器‎(feof)
    ‎如果發(fā)生其他讀數(shù)錯(cuò)誤,函數(shù)也會(huì)返回‎‎‎‎EOF,但會(huì)設(shè)置錯(cuò)誤‎‎指示器‎(ferror)

  這里的feof和ferror我們專門會(huì)放到最后講

   2.文本行輸入輸出函數(shù)

  fputs--- 文本行輸出行數(shù)聲明

int fputs ( const char * str, FILE * stream );

   參數(shù):

    const char * str --- 將被寫入輸出流的字符指針

    FILE * stream --- 輸出流

  fgets--- 文本行輸入函數(shù)聲明

char * fgets ( char * str, int num, FILE * stream );

  參數(shù):

    char * str --- 所輸入信息的存放位置

    int num --- 要讀內(nèi)容的大小

    FILE * stream --- 輸入流

示例 1:

int main()
{
 FILE* pf = fopen("data.txt", "a");// a --- 如果沒有就該文件就創(chuàng)建,有就在該文件后方繼續(xù)追加內(nèi)容 
 if (pf == NULL) // 而 w 如果存在該文件會(huì)覆蓋重寫
 {
 printf("%s\n", strerror(errno));
 return 1;
 }
 //寫一行數(shù)據(jù)
 fputs("hello\n", pf);//輸出到文件中
 fputs("hello\n", stdout);//在屏幕上顯示
 fputs("hello world\n", pf);//輸出到文件中
 fputs("hello world\n",stdout);//在屏幕上顯示


 fclose(pf);
 pf = NULL;
 return 0;
}

示例 2:

int main()
{
 char arr[100] = {0};//存放寫入的信息
 FILE* pf = fopen("data.txt", "r");
 if (pf == NULL)
 {
 printf("%s\n", strerror(errno));
 return 1;
 }
 //讀一行數(shù)據(jù)
 //fgets(arr, 100, pf);
 //printf("%s\n", arr);


 while (fgets(arr, 10, pf) != NULL)//輸出---一次讀十個(gè)
 {
 printf("%s", arr);
 }


 //fgets從標(biāo)準(zhǔn)輸入流中讀取
 fgets(arr, 100, stdin);
 printf("%s\n", arr);

 fclose(pf);
 pf = NULL;
 return 0;
}

注意:

  1.在fgets中num的大小數(shù)包含 \0 ,在內(nèi)的,如果所輸入的內(nèi)容大小大于指定的大小,fgets會(huì)強(qiáng)行截?cái)嗉?\0.

  2.返回值的處理:

    If theend-of-fileis encountered while attempting to read a character, theeof indicatoris set (feof). If this happens before any characters could be read, the pointer returned is a null pointer

     (andthe contentsofstrremain unchanged).

    If a read error occurs, theerror indicator(ferror) is set and a null pointer is also returned (but the contents pointed bystrmay have changed).

   簡(jiǎn)單點(diǎn)說:遇到錯(cuò)誤和文件結(jié)尾都會(huì)返回NULL,但會(huì)設(shè)置不同的指示器(feof,ferror)(后面會(huì)說)

   3.格式化輸入輸出函數(shù)

    fprintf--- 格式化輸出函數(shù) 聲明

int fprintf ( FILE * stream, const char * format, ... );

    fscanf--- 格式化輸入函數(shù)聲明

int fscanf ( FILE * stream, const char * format, ... );

   別看他們倆長(zhǎng)得花里胡哨的,但是使用卻和我們的printf,scanf大致相同,只是多出了一個(gè)流的填寫

   我們來看看 printf 和 scanf的聲明:

int scanf ( const char * format, ... );int printf ( const char * format, ... );

   所以我們來看一個(gè)示例:

示例 1:

struct Stu
{
 char name[20];
 int age;
 float score;
};

int main()
{
 struct Stu s = {"zhangsan", 20, 66.5f};

 FILE* pf = fopen("data.txt", "w");
 if (pf == NULL)
 {
 printf("%s\n", strerror(errno));
 return 1;
 }

 //格式化的寫入
 fprintf(pf,"%s %d %f", s.name, s.age, s.score);

 //printf("%s %d %f", s.name, s.age, s.score);//對(duì)比一下只是差了一個(gè) 流 的指定
 //關(guān)閉文件
 fclose(pf);
 pf = NULL;
 return 0;
}

注意:

   讀取錯(cuò)誤或結(jié)束時(shí),fscanf 的返回值也是EOF,判斷同 fgetc

   這里其實(shí)還有一組與它倆相似的函數(shù) ---sprintf以及sscanf (點(diǎn)擊函數(shù)名看文檔)

   它倆是干什么的呢,一個(gè)是把結(jié)構(gòu)化的數(shù)據(jù)轉(zhuǎn)換為字符串,一個(gè)是把字符串轉(zhuǎn)化為結(jié)構(gòu)化的數(shù)據(jù)

   同樣,我們來看看聲明:

[code]int sprintf ( char * str, const char * format, ... );

char * str --- 我們要把格式化生成的字符串所存放的地址

int sscanf ( const char * s, const char * format, ...);

const char * s --- 我們所要讀取的字符串

示例:

struct Stu
{
 char name[20];
 int age;
 float score;
};

int main()
{
 struct Stu s = {"zhangsan", 20, 66.5f};
 char buf[200] = { 0 };

 //sprintf可以把結(jié)構(gòu)化的數(shù)據(jù)轉(zhuǎn)換為一個(gè)字符串
 sprintf(buf, "%s %d %f", s.name, s.age, s.score);

 printf("按照字符串的形式:%s\n", buf);

 struct Stu tmp = { 0 };

 //sscanf可以把一個(gè)字符串轉(zhuǎn)換為一個(gè)結(jié)構(gòu)化的數(shù)據(jù)
 sscanf(buf, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
 printf("按照格式化的形式:%s %d %f\n", tmp.name, tmp.age, tmp.score);

 return 0;
}

4.二進(jìn)制輸入輸出函數(shù)

  fwrite--- 二進(jìn)制寫文檔

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

這個(gè)函數(shù)解釋一下就是:將來自 ptr 指向的數(shù)據(jù),一次寫size個(gè)字節(jié),共寫 count 次,輸出到 stream 指定的流中

  fread--- 二進(jìn)制讀文檔

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

這個(gè)函數(shù)解釋一下就是:將 stream 指定的流中 讀 count 次,一次讀 size 個(gè)字節(jié),存到 ptr 所指向的內(nèi)容中

示例:

// data.txt 內(nèi)容 zhangsan 20 66.500000
int main()
{
 struct Stu s = {0};
 FILE* pf = fopen("data.txt", "rb");//binary --- 二進(jìn)制
 if (pf == NULL)  // rb --- 二進(jìn)制讀
 {
 printf("%s\n", strerror(errno));
 return 1;
 }
 //讀文件-二進(jìn)制
 fread(&s, sizeof(struct Stu), 1, pf);
 printf("%s %d %f\n", s.name, s.age, s.score);

 fclose(pf);
 pf = NULL;
 return 0;
}

注:

  若讀取時(shí)發(fā)現(xiàn)讀取的內(nèi)容的個(gè)數(shù)比指定的最大個(gè)數(shù)小時(shí),就結(jié)束,然后判斷是讀到文件末尾,還是讀取失敗

示例 2:

int main()
{
 int a = 10000;
 FILE*pf = fopen("bin.dat", "wb");//二進(jìn)制寫
 if (pf == NULL)
 {
 return 1;
 }

 fwrite(&a, sizeof(int), 1, pf);
 fclose(pf);
 pf = NULL;

 return 0;
}

3.文件的隨機(jī)讀寫 

    1.seek ---根據(jù)文件指針的位置和偏移量來定位文件指針。

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

FILE * stream --- 流

long int offset --- 偏移量

int origin --- 從哪里開始,有三個(gè)選擇

  1.SEEK_SET --- 從文件頭開始

  2.SEEK_CUR --- 從當(dāng)前位置開始

  3.SEEk_END --- 從文件末尾開始

示例:

//此時(shí)文件內(nèi)容為:123456789
int main()
{
 FILE* fp = fopen("data.txt", "r");
 if (fp == NULL)
 {
 perror("\n");
 exit(1);
 }

 char a = fgetc(fp);
 printf("%c ", a);//此時(shí)結(jié)果為 1,現(xiàn)在指針指向 2

 a = fgetc(fp);//此時(shí)讀取2,指針指向 3
 printf("%c ", a);

 fseek(fp, -1, SEEK_END);//將文件指針置于文章末尾

 a = fgetc(fp);//此時(shí)讀取9,指針再次指向末尾
 printf("%c ", a);

 fseek(fp, 1, SEEK_SET);//將文件指針置于文章頭

 a = fgetc(fp);//此時(shí)讀取1,指針再次指向2
 printf("%c ", a);

 fclose(fp);
 fp = NULL;
 return 0;
}

 2.ftell ---返回文件指針相對(duì)于起始位置的偏移量

long int ftell ( FILE * stream );

3.rewind ---讓文件指針的位置回到文件的起始位置

void rewind ( FILE * stream );

示例:

int main()
{
 FILE*pf = fopen("data.txt", "r");
 if (pf == NULL)
 {
 return 1;
 }
 //讀取
 int ch = fgetc(pf);
 printf("%c\n", ch);

 ch = fgetc(pf);
 printf("%c\n", ch);
 
 //定位文件指針到文件的起始位置
 //fseek(pf, -2,SEEK_CUR);
 //fseek(pf, 0, SEEK_SET);
 //printf("%d\n", ftell(pf));

 rewind(pf);

 ch = fgetc(pf);//要在這里讀取'a'
 printf("%c\n", ch);

 fclose(pf);
 pf = NULL;
 return 0;
}

4.文件緩存區(qū)的刷新

  我們?cè)谏衔奶岬轿募彌_區(qū)的概念:

    緩沖文件系統(tǒng)是指系統(tǒng)自動(dòng)地在內(nèi)存中為程序中每一個(gè)正在使用的文件開辟一塊“文件緩沖區(qū)”。

    從內(nèi)存向磁盤輸出數(shù)據(jù)會(huì)先送到內(nèi)存中的緩沖區(qū),裝滿緩沖區(qū)后才一起送到磁盤上。

    如果從磁盤向計(jì)算機(jī)讀入數(shù)據(jù),則從磁盤文件中讀取數(shù)據(jù)輸入到內(nèi)存緩沖區(qū)(充滿緩沖區(qū)),然后再?gòu)木彌_區(qū)逐個(gè)地將數(shù)據(jù)送到程序數(shù)據(jù)區(qū)(程序變量等)。

    緩沖區(qū)的大小根據(jù)C編譯系統(tǒng)決定的。

  所以,當(dāng)我們?cè)诔绦蛑忻钣?jì)算機(jī)往文件中寫一些東西的時(shí)候,如果我們想在輸出語句已結(jié)束,文件就有內(nèi)容(即需要寫的內(nèi)容從文件緩沖區(qū)寫到了文件中),

  此時(shí),我們不妨fflush一下

   fflush --- 刷新文件緩存區(qū)

int fflush ( FILE * stream );

   參數(shù)就是我們所定義的文件指針。

示例:

#include <stdio.h>
#include <windows.h>
//VS2019 WIN10環(huán)境測(cè)試
int main()
{
 FILE* pf = fopen("test.txt", "w");
 fputs("abcdef", pf);//先將代碼放在輸出緩沖區(qū)
 printf("睡眠10秒-已經(jīng)寫數(shù)據(jù)了,打開test.txt文件,發(fā)現(xiàn)文件沒有內(nèi)容\n");
 Sleep(10000);
 printf("刷新緩沖區(qū)\n");
 fflush(pf);//刷新緩沖區(qū)時(shí),才將輸出緩沖區(qū)的數(shù)據(jù)寫到文件(磁盤)
 //注:fflush 在一些編譯器上并不能使用
 printf("再睡眠10秒-此時(shí),再次打開test.txt文件,文件有內(nèi)容了\n");
 Sleep(10000);
 fclose(pf);
 //注:fclose在關(guān)閉文件的時(shí)候,也會(huì)刷新緩沖區(qū)
 pf = NULL;

 return 0;
}

三.一個(gè)易被誤用的點(diǎn)

feof的錯(cuò)誤使用

  在剛才的講解中,我們已經(jīng)都說過了各輸入函數(shù)遇到錯(cuò)誤時(shí)的返回值,所以我們?cè)趯懳募h(huán)讀取的循環(huán)條件時(shí),一定要注意各函數(shù)的返回值的區(qū)別 !

  在不滿足循環(huán)條件后 判斷是發(fā)生錯(cuò)誤跳出,還是讀到文本末尾結(jié)束(這就是前面所說到的指示器 feof --- 文本結(jié)束, ferror --- 遇到錯(cuò)誤)

如圖:

示例:

int main()
{
 FILE*pf = fopen("data.txt", "r");
 if (pf == NULL)
 {
 return 1;
 }
 //讀取
 int ch = 0;
 while ((ch = fgetc(pf)) != EOF)
 {
 printf("%c ", ch);
 }
 //找結(jié)束的原因
 if (ferror(pf))
 {
 printf("讀取是發(fā)生錯(cuò)誤,失敗,而結(jié)束\n");
 }
 else if (feof(pf))
 {
 printf("遇到文件末尾,而結(jié)束的\n");
 }

 fclose(pf);
 pf = NULL;
 return 0;
}

所以,我們?cè)谌粘J褂玫臅r(shí)候要注意這個(gè)點(diǎn)!

總結(jié)

到此這篇關(guān)于C語言文件操作入門詳解教程的文章就介紹到這了,更多相關(guān)C語言文件操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于Matlab實(shí)現(xiàn)野狗優(yōu)化算法的示例代碼

    基于Matlab實(shí)現(xiàn)野狗優(yōu)化算法的示例代碼

    野狗優(yōu)化算法(Dingo?Optimization?Algorithm,?DOA)模仿澳大利亞野狗的社交行為。DOA算法的靈感來源于野狗的狩獵策略,即迫害攻擊、分組策略和食腐行為。本文將通過Matlab實(shí)現(xiàn)這一算法,感興趣的可以了解一下
    2022-04-04
  • C++使用string的大數(shù)取模運(yùn)算(5)

    C++使用string的大數(shù)取模運(yùn)算(5)

    這篇文章主要為大家詳細(xì)介紹了C++使用string的大數(shù)取模運(yùn)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • C++?二叉樹的實(shí)現(xiàn)超詳細(xì)解析

    C++?二叉樹的實(shí)現(xiàn)超詳細(xì)解析

    二叉樹可以簡(jiǎn)單理解為對(duì)于一個(gè)節(jié)點(diǎn)來說,最多擁有一個(gè)上級(jí)節(jié)點(diǎn),同時(shí)最多具備左右兩個(gè)下級(jí)節(jié)點(diǎn)的數(shù)據(jù)結(jié)構(gòu)。本文將詳細(xì)介紹一下C++中二叉樹的實(shí)現(xiàn)和遍歷,需要的可以參考一下
    2022-03-03
  • C++標(biāo)準(zhǔn)庫(kù)bitset類型的簡(jiǎn)單使用方法介紹

    C++標(biāo)準(zhǔn)庫(kù)bitset類型的簡(jiǎn)單使用方法介紹

    這篇文章主要介紹了C++標(biāo)準(zhǔn)庫(kù)bitset類型的簡(jiǎn)單使用方法,需要的朋友可以參考下
    2017-07-07
  • C++實(shí)現(xiàn)冒泡排序(BubbleSort)

    C++實(shí)現(xiàn)冒泡排序(BubbleSort)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)冒泡排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言實(shí)現(xiàn)貪吃蛇游戲代碼

    C語言實(shí)現(xiàn)貪吃蛇游戲代碼

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)貪吃蛇游戲代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C++ map 根據(jù)value找key的實(shí)現(xiàn)

    C++ map 根據(jù)value找key的實(shí)現(xiàn)

    今天小編就為大家分享一篇C++ map 根據(jù)value找key的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • 淺談C語言轉(zhuǎn)義字符和格式控制符

    淺談C語言轉(zhuǎn)義字符和格式控制符

    下面小編就為大家?guī)硪黄獪\談C語言轉(zhuǎn)義字符和格式控制符。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-08-08
  • C語言 makefile學(xué)習(xí)及實(shí)現(xiàn)實(shí)例

    C語言 makefile學(xué)習(xí)及實(shí)現(xiàn)實(shí)例

    這篇文章主要介紹了C語言 makefile學(xué)習(xí)及實(shí)現(xiàn)實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Qt透明無邊框窗口的實(shí)現(xiàn)示例

    Qt透明無邊框窗口的實(shí)現(xiàn)示例

    這篇文章主要介紹了Qt透明無邊框窗口的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評(píng)論