真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

22、一文帶你掌握C語(yǔ)言文件操作-創(chuàng)新互聯(lián)

一文帶你掌握C語(yǔ)言文件操作
  • 文件操作
    • 1 文件相關(guān)
      • 1.1 文件名
      • 1.2 文件類(lèi)型
      • 1.3 文件緩沖區(qū)
      • 1.4 文件指針
    • 2 文件的打開(kāi)和關(guān)閉
    • 3 文件的順序讀寫(xiě)
      • 3.1 字符輸入輸出
      • 3.2 文本輸入輸出
      • 3.3 讀取有格式的文件
      • 3.4 二進(jìn)制輸入輸出
    • 4 文件的隨機(jī)讀寫(xiě)
      • `1、fseek`
      • `2、ftell`
      • `3、rewind`
    • 5 文件結(jié)束判定
      • 被錯(cuò)誤使用的feof

創(chuàng)新互聯(lián)建站是一家以成都網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)、品牌設(shè)計(jì)、軟件運(yùn)維、成都網(wǎng)站營(yíng)銷(xiāo)、小程序App開(kāi)發(fā)等移動(dòng)開(kāi)發(fā)為一體互聯(lián)網(wǎng)公司。已累計(jì)為成都汽車(chē)玻璃修復(fù)等眾行業(yè)中小客戶(hù)提供優(yōu)質(zhì)的互聯(lián)網(wǎng)建站和軟件開(kāi)發(fā)服務(wù)。文件操作 1 文件相關(guān) 1.1 文件名

一個(gè)文件要有一個(gè)唯一的標(biāo)識(shí),以便用戶(hù)識(shí)別和引用。

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

c:\code\test.txt

1.2 文件類(lèi)型

根據(jù)數(shù)據(jù)的組織形式,對(duì)于數(shù)據(jù)文件來(lái)說(shuō),一般分為二進(jìn)制文件和文本文件

  • 二進(jìn)制文件

    數(shù)據(jù)在內(nèi)存中以二進(jìn)制的形式存儲(chǔ)

  • 文本文件

    要求在外存上以ASCII碼的形式存儲(chǔ),則需要在存儲(chǔ)前轉(zhuǎn)換。

1.3 文件緩沖區(qū)

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

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

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

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

1.4 文件指針

文件類(lèi)型指針:簡(jiǎn)稱(chēng)文件指針

每個(gè)被使用的文件,都在內(nèi)存中開(kāi)辟了一個(gè)相應(yīng)的文件信息區(qū),用來(lái)存放文件的相關(guān)(如文件名,文件狀態(tài),文件當(dāng)前位置等),這些信息保存在一個(gè)結(jié)構(gòu)體變量中。

該結(jié)構(gòu)體類(lèi)型是有系統(tǒng)聲明的,取名FILE

typdef struct _iobuf FILE

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

一般都是通過(guò)一個(gè)FILE類(lèi)型的指針,來(lái)維護(hù)這個(gè)FILE結(jié)構(gòu)的變量,這樣使用起來(lái)會(huì)很方便。

創(chuàng)建一個(gè)FILE*的指針變量

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

也就是說(shuō),通過(guò)文件指針,能夠找到與它相關(guān)聯(lián)的文件。

2 文件的打開(kāi)和關(guān)閉
  • 文件在讀寫(xiě)之前應(yīng)該先打開(kāi)文件
  • 在使用結(jié)束之后應(yīng)該關(guān)閉文件

在編寫(xiě)程序的時(shí)候,在打開(kāi)文件的同時(shí),都會(huì)返回一個(gè)FILE*的指針變量指向該文件,也相當(dāng)于建立了指針和文件的關(guān)系

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

int flcose(FILE* stream);

文件的打開(kāi)方式有下面幾種

文件使用方式含義如果指定文件不存在
“r”(只讀)為了輸入數(shù)據(jù),打開(kāi)一個(gè)已經(jīng)存在的文本文件出錯(cuò)
“w”(只寫(xiě))為了輸出數(shù)據(jù),打開(kāi)一個(gè)文本建立一個(gè)新文件
“a”(追加)向文本文件尾添加數(shù)據(jù)出錯(cuò)
“rb”(只讀)為了輸入數(shù)據(jù),打開(kāi)一個(gè)二進(jìn)制文件出錯(cuò)
“wb”(只寫(xiě))為了輸出數(shù)據(jù),打開(kāi)一個(gè)二進(jìn)制文件建立一個(gè)新文件
“ab”(追加)向一個(gè)二進(jìn)制文件尾添加數(shù)據(jù)出錯(cuò)
“r+”(讀寫(xiě))為了讀和寫(xiě),打開(kāi)一個(gè)文本文件出錯(cuò)
“w+”(讀寫(xiě))為了讀和寫(xiě),建立一個(gè)新的文件建立一個(gè)新文件
“a+”(讀寫(xiě))打開(kāi)一個(gè)文件,在文件尾進(jìn)行讀寫(xiě)建立一個(gè)新文件
“rb+”(讀寫(xiě))為了讀和寫(xiě)打開(kāi)一個(gè)二進(jìn)制文件出錯(cuò)
“rw+”(讀寫(xiě))為了讀和寫(xiě),新建一個(gè)二進(jìn)制文件建立一個(gè)新文件
“ab+”(讀寫(xiě))打開(kāi)一個(gè)二進(jìn)制文件,在文件尾進(jìn)行讀寫(xiě)建立一個(gè)新文件

在寫(xiě)文件名的時(shí)候,可以是相對(duì)路徑,也可以是絕對(duì)路徑

注意點(diǎn)

  • w如果存在文件會(huì)清空,如果文件不存在,就建立一個(gè)新文件。
3 文件的順序讀寫(xiě)
功能函數(shù)名適用于
字符輸入函數(shù)fgetc所有輸入流
字符輸出函數(shù)fputc所有輸出流
文本行輸入函數(shù)fgets所有輸入流
文本上輸出函數(shù)fputs所有輸出流
格式化輸入函數(shù)fscanf所有輸入流
格式化輸出函數(shù)fprintf所有輸出流
二進(jìn)制輸入fread文件
二進(jìn)制輸出fwrite文件
3.1 字符輸入輸出

讀文件(字符輸入)*

int main()
{FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{// 打開(kāi)失敗
		printf("%s\n",strerror(errno));
		return 0;
	}

	// 打開(kāi)成功

	// 讀文件
	printf("%c ", fgetc(pf));
	printf("%c ", fgetc(pf));
	printf("%c ", fgetc(pf));
	printf("%c ", fgetc(pf));
	printf("%c ", fgetc(pf));

	// 關(guān)閉文件
	fclose(pf);
	pf = NULL; // 相當(dāng)于free一樣
}

寫(xiě)文件(字符輸出)

int main()
{FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{// 打開(kāi)失敗
		printf("%s\n",strerror(errno));
		return 0;
	}

	// 打開(kāi)成功

	// 寫(xiě)文件
	fputc('h', pf);
	fputc('e', pf);
	fputc('l', pf);
	fputc('l', pf);
	fputc('o', pf);

	// 關(guān)閉文件
	fclose(pf);
	pf = NULL; // 相當(dāng)于free一樣
}

小知識(shí)點(diǎn)?。?!

鍵盤(pán)和屏幕這兩個(gè)輸入輸出流

  • 從鍵盤(pán)輸入
  • 輸出到屏幕

鍵盤(pán)和屏幕都是外部設(shè)備

  • 鍵盤(pán)–標(biāo)準(zhǔn)輸入設(shè)備
  • 屏幕–標(biāo)準(zhǔn)輸出設(shè)備

這兩個(gè)是程序默認(rèn)打開(kāi)的兩個(gè)流設(shè)備

分別對(duì)應(yīng)著stdin/stdout/stderr

這三個(gè)流的類(lèi)型都是FILE*

也就是說(shuō),鍵盤(pán)其實(shí)就是對(duì)應(yīng)著stdin

屏幕對(duì)應(yīng)著stdout

因此我們可以這樣設(shè)計(jì)程序

// 因?yàn)?fgetc/foutc 可以處理所有的輸入輸出流,因此鍵盤(pán)和屏幕也可以處理

在這里插入圖片描述

3.2 文本輸入輸出

char* fgets(char *string, int n, FILE *stream);

string:從stream讀的內(nèi)容,放到string中去。就是一個(gè)緩沖的字符數(shù)組(字符串)

n:最多讀取多少個(gè)字符

注意的是 string 在讀取之后,本身就有一個(gè)換行,這個(gè)換行本身就是文件里面的,只不過(guò)換行是空白的隱藏起來(lái)了。

讀文件

int main()
{char buf[1024] = {0};
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{printf("%s\n", strerror(errno));
		return 0;
	}
	// 讀文件
	fgets(buf,1024, pf);
	printf("%s", buf);
    // puts(buf);  如果這里使用 puts,puts天生就會(huì)在末尾加換行,會(huì)出現(xiàn)多個(gè)空行的情況
	fgets(buf, 1024, pf);
	printf("%s", buf);

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

寫(xiě)文件

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

int main()
{char buf[1024] = {0};
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{printf("%s\n", strerror(errno));
		return 0;
	}
	// 寫(xiě)文件
	fputs("hello 你好\n", pf);
	fputs("hello world", pf);


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

操作鍵盤(pán)和屏幕讀取輸出一行

int main()
{char buf[1024];

	fgets(buf,1024,stdin);// 從標(biāo)準(zhǔn)輸入流讀取
	fputs(buf, stdout);// 輸出到標(biāo)準(zhǔn)輸出流
	return 0;
}

這種寫(xiě)法相當(dāng)于

gets(buf); puts(buf);

3.3 讀取有格式的文件

int printf(const char* format [,argument]...);// 其實(shí)這里默認(rèn)是針對(duì) stdout的

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

除了比printf多了一個(gè)文件流參數(shù)之外,其他都一樣。

其實(shí)printf默認(rèn)是針對(duì)stdout的,也就是說(shuō)它的流是stdout

fprintf輸出函數(shù) 寫(xiě)文件

struct S
{int n;
	float score;
	char arr[10];
};
int main()
{struct S s[2] = {{100, 3.14f, "hello" }, {200,8.88f,"world"} };
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{return 0;
	}
	// 格式化寫(xiě)文件
	fprintf(pf, "%d %f %s\n", s[0].n, s[0].score, s[0].arr);
	fprintf(pf, "%d %f %s\n", s[1].n, s[1].score, s[1].arr);

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

fscanf 輸出讀文件

struct S
{int n;
	float score;
	char arr[10];
};
int main()
{struct S s[2] = {0};
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{return 0;
	}
	// 格式化讀文件 -- 首先要設(shè)置好存這個(gè)數(shù)據(jù)的變量 或者 結(jié)構(gòu)體
	// 一定注意到在 scanf時(shí),變量要用其地址來(lái)接收
	fscanf(pf, "%d %f %s", &s[0].n, &s[0].score, s[0].arr);
	printf( "%d %f %s", s[0].n, s[0].score, s[0].arr);
	fscanf(pf, "%d %f %s", &s[1].n, &s[1].score, s[1].arr);
	printf("%d %f %s", s[1].n, s[1].score, s[1].arr);




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

標(biāo)準(zhǔn)輸入輸出流中讀取

struct S
{int n;
	float score;
	char arr[10];
};
int main()
{struct S s[2] = {0};
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{return 0;
	}
	// 格式化讀文件 -- 首先要設(shè)置好存這個(gè)數(shù)據(jù)的變量 或者 結(jié)構(gòu)體
	// 一定注意到在 scanf時(shí),變量要用其地址來(lái)接收
	fscanf(stdin, "%d %f %s", &s[0].n, &s[0].score, s[0].arr);
	
	fprintf(stdout, "%d %f %s", s[0].n, s[0].score, s[0].arr);



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

scanf/printf是針對(duì)標(biāo)準(zhǔn)輸入輸出流的格式化輸入輸出語(yǔ)句

fscanf/fprintf是針對(duì)所有輸入輸出流的格式化輸入輸出語(yǔ)句

sscanf/sprintf 是針對(duì)字符串的格式化輸入輸出,從字符串中讀,輸出到字符串中去

int main()
{struct S s = {100, 3.14f, "hello"};
    struct S tmp = {0};
    char buf[1024] = {0};
    
    // 把格式化的數(shù)據(jù)轉(zhuǎn)換成字符串,存儲(chǔ)到buf
    sprintf(buf, "%d %f %s", s.n, s.score, s.arr);
    
    // 從buf中讀取格式化的數(shù)據(jù)到tmp中
    sscanf(buf, "%d %f %s", &(tmp.n), &(tmp.float), tmp.arr);
}
3.4 二進(jìn)制輸入輸出

把結(jié)構(gòu)體學(xué)生的信息存入到文件中去,怎么寫(xiě)呢?

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

buffer: 要寫(xiě)的內(nèi)容

size:元素的大小

count:元素的個(gè)數(shù)

struct S
{char name[20];
	int age;
	double score;
};
int main()
{struct S s = {"張三", 20, 64.5};
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{return 0;
	}
	
	// 二進(jìn)制寫(xiě)文件
	fwrite(&s, sizeof(struct S), 1, pf);



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

fread 讀二進(jìn)制文件

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

int main()
{//struct S s = {"張三", 20, 64.5};
	struct S tmp = {0};
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{return 0;
	}
	
	// 二進(jìn)制寫(xiě)文件
	//fwrite(&s, sizeof(struct S), 1, pf);

	// 二進(jìn)制讀文件
	fread(&tmp, sizeof(struct S), 1, pf); // 二進(jìn)制讀的文件,直接讀給這么大的內(nèi)存空間
	printf("%s %d %f\n", tmp.name, tmp.age, tmp.score);
	// 關(guān)閉
	fclose(pf);
	pf = NULL;
}
4 文件的隨機(jī)讀寫(xiě)1、fseek

根據(jù)文件指針的位置和偏移量來(lái)定位文件指針

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

offset:偏移量。單位是字節(jié)

  • 正值代表向后偏移
  • 負(fù)值代表向前偏移

origin:文件指針的當(dāng)前位置

  • SEEK_CUR:文件指針當(dāng)前位置
  • SEEK_END:文件末尾(在最后一個(gè)字符的后面,而不是最后一個(gè)字符)
  • SEEK_SET:文件起始位置

通過(guò)調(diào)整文件指針,以當(dāng)前位置為起點(diǎn),根據(jù)偏移量來(lái)調(diào)整。

int main()
{	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{return 0;
	}
	
	// 定位文件指針
	// 我們默認(rèn)的 test.txt 里面存放的數(shù)據(jù)是 abcdef
	fseek(pf, 2, SEEK_CUR); // 從當(dāng)前位置向后偏移 2 字節(jié),就是從 c 開(kāi)始
	//fseek(pf, 2, SEEK_CUR);  從末尾向前偏移 2 字節(jié),e

	// 讀取文件
	int ch = fgetc(pf);
	printf("%c\n", ch);  // c



	// 關(guān)閉
	fclose(pf);
	pf = NULL;
}
2、ftell

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

long int ftell(FILE* stream);

int main()
{	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{return 0;
	}
	
	// 定位文件指針
	// 我們默認(rèn)的 test.txt 里面存放的數(shù)據(jù)是 abcdef
	fseek(pf, -2, SEEK_END);
	int pos = ftell(pf); 
	printf("%d\n", pos); // 4

	// 讀取文件
	


	// 關(guān)閉
	fclose(pf);
	pf = NULL;
}
3、rewind

讓文件指針的位置回到文件的起始位置

void rewind(FILE* stream);

int ch = fgetc(pf);
printf("%c\n", ch);

rewind(pf);
printf("%c\n", ch); // 這里依然是a
5 文件結(jié)束判定 被錯(cuò)誤使用的feof

在文件讀取過(guò)程中,不能用feof函數(shù)的返回值直接用來(lái)判斷文件是否結(jié)束

這個(gè)是應(yīng)用于當(dāng)文件讀取結(jié)束的時(shí)候,判斷是讀取失敗結(jié)束,還是遇到文件尾結(jié)束

  • 文本文件讀取是否結(jié)束,判斷返回值是否為EOF或者NULL
    • fgetc判斷是否為EOF
    • fgets判斷是否為NULL
  • 二進(jìn)制文件的讀取結(jié)束判斷,判斷返回值是否小于實(shí)際要讀的個(gè)數(shù)
    • fread判斷返回值是否小于實(shí)際要讀的個(gè)數(shù)
while((ch = fgetc(pf)) != EOF)
{putchar(ch);
}

if (ferror(pf)) // 判斷是否遇到錯(cuò)誤而退出
{printf("error\n");
}else if(feof(of)) // 判斷是否遇到 EOF而退出
{printf("end of file \n");
}

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


分享題目:22、一文帶你掌握C語(yǔ)言文件操作-創(chuàng)新互聯(lián)
當(dāng)前地址:http://weahome.cn/article/eedoh.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部