语言基础程序 7_第1页
语言基础程序 7_第2页
语言基础程序 7_第3页
语言基础程序 7_第4页
语言基础程序 7_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言程序设计项目化教程(AI助学)(微课版)项目9

文件管理系统情景导入

小辰的家人开了一家小型零售店,每天要处理大量商品信息:进货、销售、库存盘点……。起初,家人用笔记本手工记录,后来改用普通文本文件存储,但几百种商品的数据查询要从头到尾扫描,效率低下且经常出错。家人的困扰让小辰萌生了开发文件管理系统的想法,他希望该系统能满足这些需求:①快速定位到任意商品的信息,就像在书架上直接抽书一样便捷;②数据存储紧凑高效,不占用过多空间;③断电重启后数据完好保存;④支持快速更新库存和销售记录。基于C语言文件处理技术,小辰着手开发文件管理系统,通过二进制文件存储、随机访问定位、数据块快速读写等核心技术,帮家人实现商品数据的高效管理。知识图谱学习要点理解文件的概念及其分类(文本文件vs二进制文件)。掌握文件型指针(FILE*)的概念和作用。掌握文件操作的基本流程:打开、读写、关闭。熟悉常用的文件打开模式("r","w","a","rb","wb","ab"等)及其区别。掌握基本的文件读写函数。培养文件操作规范意识,提升程序健壮性。实现库存数据文件管理任务9任务9实现库存数据文件管理任务描述图9-2文件管理系统效果图设计一个简单的文件管理系统,实现库存数据的文件存储与读取功能。系统能够将商品信息保存到文件中,并在需要时从文件中读取数据,效果如图9-12所示。9.1.1文件概述知识准备文件概述

程序处理的数据基本都存储在内存中。一旦程序结束,数据就丢失了,

如果我们想长期保存数据,比如学生的成绩、图书馆的借阅记录,该怎么办呢?对,就是要用文件。

在程序中经常对文件进行操作,例如打开一个文件、向文件写入内容。本任务将对C语言中的各种文件操作进行详细讲解。文件学习内容知识准备对文件读写之前应该“打开”该文件,在使用结束之后应“关闭”该文件。文件概述文件的读和写是文件的常用操作,C语言提供了多种文件读写函数。文件的打开和关闭0201文件学习内容03文件的读写操作在程序中经常对文件进行操作,例如打开一个文件、向文件写入内容。本任务将对C语言中的各种文件操作进行详细讲解。9.1.1文件概述知识准备1.文件的定义图9-1文件集合图“文件”是指一组相关数据的有序集合。每个文件都有一个文件名,包括文件名和扩展名,如图9-1所示。在C语言中,我们实际上已经多次使用了文件,包括源程序文件、库文件、可执行程序等。文件标识一个文件要有一个唯一的文件标识,以便用户识别和引用。文件标识包括3部分:文件路径、文件名主干、文件后缀。文件路径表示文件在外部存储设备中的位置。文件名主干的命名规则遵循标识符的命名规则。文件后缀用来表示文件的性质。9.1.1文件概述知识准备2.文件的分类

字符一律以ASCII形式存储,数值型数据既可以用ASCII形式存储,也可以用二进制形式存储。数值型文件可以用ASCII码、十进制、二进制等表示。

根据数据的组织形式,数据文件可分为ASCII文件和二进制文件。数据在内存中是以二进制形式存储的,如果不加转换地输出到外存,就是二进制文件,可以认为它就是存储在内存的数据的映像,所以也称之为映像文件(imagefile)。如果要求在外存上以ASCII代码形式存储,则需要在存储前进行转换。ASCII文件又称文本文件(textfile),每一个字节存放一个字符的ASCII代码。图9-3

数值型文件表示9.1.1文件概述知识准备3.文件指针若用指针变量指向一个文件,此指针就称为文件指针。

定义形式如下:

FILE*指针变量标识符fp指向FILE结构的指针变量,也就是说,通过文件指针变量能够找到与它关联的文件。也可以把fp称为一个文件的指针。如果有n个文件,应设n个指针变量,分别指向n个FILE类型变量,以实现对n个文件的访问。为方便起见,通常将这种指向文件信息区的指针变量简称为指向文件的指针变量。说明:例如:

FILE*fp;

//定义一个指向FILE类型数据的指针变量其中FILE应为大写,它实际上是由系统定义的一种结构,该结构中含有文件名、文件状态和文件当前位置等信息。9.1.2文件的打开和关闭知识准备1.文件的打开在C语言中,文件的操作都是由库函数来完成的。用fopen函数打开数据文件。一般形式为:

说明:例如:

FILE*fp;fp=fopen("file.txt","r");其中文件指针名必须被声明为FILE类型的指针变量;文件名是打开文件的文件名,可用字符串常量或字符串数组表示,使用方式是指文件的类型和操作要求。

文件指针名=fopen(文件名,使用文件方式);表9-1文件使用方式及含义9.1.2文件的打开和关闭知识准备2.文件的关闭

所谓“关闭”是指撤销文件信息区和文件缓冲区,使文件指针变量不再指向该文件,显然就无法进行对文件的读写了。

一般形式为:

注意:例如:

fclose(fp);正常完成关闭文件操作时,fclose()返回值为0。如返回非零值则表示有错误发生。

fclose(文件指针);表9-1文件使用方式及含义9.1.3文件的读写操作知识准备1.字符读写函数

字符读写函数包括读字符函数和写字符函数,如表9-2所示。

fgetc的第1个字母f代表文件(file),中间的get表示“获取”,最后一个字母c表示字符(character),fgetc的含义很清楚,

从文件读取一个字符。fputc也类似。表9-2字符读写函数【例9-1】在D:\STUDY\下有文件mm.txt,应用文件的读函数读取文件mm.txt内容,并显示输出,如图9-4所示。图9-4

D:\STUDY\mm.txt9.1.3文件的读写操作知识准备1.字符读写函数1.#include

"stdio.h"

2.//#include

"conio.h"

3.#include

"stdlib.h"

4.void

main()

5.{

6.

7.FILE*fp;

8.char

ch;

9.if((fp=fopen("D:\\tudy\\mm.txt","rt"))==NULL)10.{

printf("\nCannotopenfile!");11.

getch();12.exit(1);13.}14.ch=fgetc(fp);

15.while(ch!=EOF)

16.{17.

putchar(ch);

18.

ch=fgetc(fp);19.}20.fclose(fp);

21.}22.

运行结果a12rgg【温馨提示】(1)在fgetc函数调用中,读取的文件必须是以读或读写方式打开的。(2)读取字符的结果也可以不向字符变量赋值,例如fgetc(fp)。这样读出的字符不能保存。(3)在文件内部有一个位置指针。它用来指向文件的当前读写字节。在文件打开时,该指针总是指向文件的第一个字节。使用fgetc函数后,该位置指针将向后移动一个字节,因此可连续、多次使用fgetc函数来读取多个字符。(4)注意去区别文件指针和文件内部的位置指针。文件指针是指向整个文件的,须在程序中定义和声明,只要不重新赋值,文件指针的值是不变的;文件内部的位置指针用以指示文件内部的当前读写位置,每读写一次,该指针均向后移动,它无须在程序中定义或声明,而是由系统自动设置的。9.1.3文件的读写操作知识准备1.字符读写函数运行结果inputsstring:filefile

【例9-2】在D:\STUDY\下有文件nn.txt,应用文件的写函数向文件nn.txt写入内容,并显示输出。1.#include

"stdio.h"

2.#include

"stdlib.h"

3.void

main()

4.{

5.FILE*fp;

6.char

ch;

7.if((fp=fopen("D:\\study\\nn.txt","wt+"))==NULL)

8.{

printf("\nCannotopenfile!");

9.

getch();10.exit(1);11.}12.printf("inputsstring:\n");13.ch=getchar(

);

14.while(ch!='\n')

15.{16.

fputc(ch,fp);

17.

ch=getchar(

);

18.}19.rewind(fp);20.ch=fgetc(fp);

21.while(ch!=EOF)22.{23.putchar(ch);24.ch=fgetc(fp);

25.}26.printf("\n");27.fclose(fp);

28.}

请同学们根据运行结果自行验证。

【温馨提示】(1)被写入的文件可以用写、读写、追加方式打开,用写或读写方式打开一个已

存在的文件时,原文件内容将被替换。(2)写入字符从文件首开始。如需保留原有文件内容,希望写入的字符从文件末开

始,必须以追加的方式打开文件,如果文件不存在,则创建新文件。(3)每写入一个字符,文件内部的位置指针向后移动一个字节。(4)fputc函数有一个返回值,写入成功则返回写入的字符,不成功则返回EOF。9.1.3文件的读写操作知识准备2.字符串读写函数字符串读写函数包括读字符串函数和写字符串函数,如表9-3所示。fgets和fgets这两个函数的功能类似于gets和puts函数,只是gets和puts以终端为读写对象,而fgets和fputs函数以指定的文件作为读写对象。

ffgets中最后一个字母s表示字符串(string)。fputs其作用是从文件读入一个字符串。字符串末尾的′\0′不输出。若输出成功,函数值为0;失败时,函数值为EOF(即-1)。【例9-3】从mm.txt文件中读入一个含5个字符的字符串,并在屏幕上输出。表9-3字符串读写函数1.#include

"stdio.h"

2.#include

"stdlib.h"

3.void

main()

4.{

5.FILE*fp;

6.char

str[11];

7.if((fp=fopen("D:\\study\\mm.txt","rt"))==NULL)

8.{

printf("\nCannotopenfile!");

9.

getch();10.

exit(1);11.}12.fgets(str,4,fp);

13.printf("%s\n",str);

14.fclose(fp);15.}

运行结果a12rg

请同学们根据运行

结果自行验证。

9.1.3文件的读写操作知识准备2.字符串读写函数运行结果inputastring:中国济南123456file中国济南

请同学们根据运行

结果自行验证。

【例9-4】向文件bb.txt中追加一个字符串。1.#include

"stdio.h"

2.#include

"stdlib.h"

3.void

main()

4.{

5.FILE*fp;

6.char

ch,st[30];

7.if((fp=fopen("D:\\study\\bb.txt","at+"))==NULL)

8.{

printf("\nCannotopenfile!");

9.

getch();10.

exit(1);11.}12.printf("inputastring:");13.scanf("%s",st);14.//gets(st);15.fputs(st,fp);

16.rewind(fp);17.ch=fgetc(fp);18.while(ch!=EOF)

19.{putchar(ch);20.ch=fgetc(fp);21.}22.printf("");

23.fclose(fp);24.}“123456file”是文件bb.txt里原有的字符,“中国济南”是追加的,首先,第7行以读写方式打开一个文本文件bb.txt,如图9-7所示,通过键盘输入字符,第15行通过fputs函数写入字符串,通过rewind函数把文件内部指针移到文件首,最后通过while循环显示当前文件的全部内容,如图9-8所示。分

图9-7原文件bb.txt

图9-8写入后文件bb.txtfread(buffer,size,count,fp);

9.1.3文件的读写操作知识准备3.数据块读写函数C语言中主要的数据块读写函数是fread()和fwrite(),它们定义在stdio.h头文件中。

fread()函数的一般形式:

【例9-5】从键盘输入三个学生的数据,写入到一个文件中,再读出这三个学生的数据并将其显示在屏幕上。功能:从fp所指的文件中,每次读size个字节送入数组buffer中,连续读count次,即读count*size个字节到数组buffer中。其中buffer是一个指针,表示存放输入数据的首地址。fp表示文件指针。fwrite()函数的一般形式:ffwrite(buffer,size,count,fp);

功能:从数组buffer中取出count*size个字节数据写入fp所指向的文件中。其中buffer是一个指针,表示输出数据的首地址。fp表示文件指针。fread(buffer,size,count,fp);

1.#include

<stdio.h>

2.#include

<stdlib.h>

3.typedef

struct

{

4.

int

id;

5.

char

name[50];

6.

float

score;

7.}

Student;

8.int

main()

{

9.int

i;

10.

FILE*file;11.

Student

students[3],

readStudents[3];12.

//初始化学生数据13.

students[0]

=

(Student){1,

"张三",

85.5};14.

students[1]

=

(Student){2,

"李四",

92.0};15.

students[2]

=

(Student){3,

"王五",

78.5};16.

//写入数据到文件17.

file=

fopen("students.dat",

"wb");18.

if

(file==

NULL)

{19.

printf("无法打开文件进行写入!\n");20.

return

1;21.

}9.1.3文件的读写操作知识准备3.数据块读写函数运行结果成功写入3个学生记录成功读取3个学生记录:学生1:ID=1,姓名=张三,分数=85.5学生2:ID=2,姓名=李四,分数=92.0学生3:ID=3,姓名=王五,分数=78.522.

size_t

written=

fwrite(students,

sizeof(Student),

3,

file);23.

printf("成功写入%zu个学生记录\n",

written);24.

fclose(file);25.

//从文件读取数据26.

file=

fopen("students.dat",

"rb");27.

if

(file==

NULL)

28.{29.

printf("无法打开文件进行读取!\n");30.

return

1;31.

}32.

size_t

read=

fread(readStudents,

sizeof(Student),

3,

file);33.

printf("成功读取%zu个学生记录:\n",

read);34.

//显示读取的数据36.{37.

printf("学生%d:ID=%d,姓名=%s,分数=%.1f\n",

38.

i+1,

readStudents[i].id,

readStudents[i].name,

readStudents[i].score);39.

}40.

fclose(file);41.

return

0;42.}

分析:程序定义了一个Student结构体,包含学号、姓名和分数,使用fwrite()将3个学生记录写入二进制文件,使用fread()从文件中读取数据到另一个结构体数组,最后显示读取的学生信息。【温馨提示】数据块读写函数适用于二进制文件操作,它们可以高效地读写大型数据块,适合处理结构化和数组数据,需要注意字节序问题,特别是在不同平台间传输数据时这两个函数是C语言中处理文件I/O的重要工具,特别适合处理结构化数据的批量读写操作。9.1.3文件的读写操作知识准备4.格式化读写字符fprintf函数和fscanf函数,对文件进行格式化输入输出,从函数名可以看到,它们只是在printf和scanf的前

面加了一个字母f。它们的作用与printf函数和scanf函数相仿,都是格式化读写函数。只有一点不同:fprintf和fscanf函数的读写对象不是终端而是文件。

scanf(文件指针,格式字符串,输入表列);

按照格式字符串要求,将文件指针所指向的文件中数据顺序读入到输入表列中。例如:fscanf(fp,"%d%s",&i,s);

fprintf(文件指针,格式字符串,输出表列);

按照格式字符串要求,将输出表列中的内容依次写入到文件指针所指向的文件中。例如:fprintf(fp,"%d%c",j,ch);

它们的一般调用方式为:

9.14文件的定位知识准备rewind函数和fseek函数对文件进行顺序读写比较容易理解,也容易操作,但有时效率不高。而随机访问不是按数据在文件中的物理位置次序进行读写,而是可以对任何位置上的数据进行访问,显然这种方法比顺序访问效率高得多。实现随机读写的关键是按要求移动位置指针,这被称为文件的定位。

移动文件内部的位置指针的函数有两个:rewind函数和fseek函数。

1.rewind函数

2.fseek函数rewind(文件指针);

用rewind函数使文件位置标记指向文件开头,rewind函数的作用是使文件位置标记重新返回文件的开头,此函数没有返回值。fseek(文件类型指针,位移量,起始点);

用fseek函数改变文件位置标记,fseek函数一般用于二进制文件。9.14文件的定位知识准备rewind函数和fseek函数【例9-6】有一个文件(file1.txt),内有一些信息。要求把它复制到另一文件(file2.txt)上,并输出显示。

1.#include<stdio.h>

2.int

main()

3.{char

ch;

4.FILE*fp1,*fp2;

5.fp1=fopen("D:\\study\\file1.txt","r");//打开输入文件file1.txt

6.fp2=fopen("D:\\study\\file2.txt","w");//打开输出文件file2.txt

7.ch=getc(fp1);//从file1.txt文件读入第一个字符

8.while(!feof(fp1))//当未读取文件尾标志

9.{putchar(ch);//在屏幕输出一个字符10.ch=getc(fp1);//再从file1.txt文件读入一个字符11.}12.putchar(10);//在屏幕执行换行13.rewind(fp1);//使文件位置标记返回文件开头14.ch=getc(fp1);//从file1.txt文件读入第一个字符15.while(!feof(fp1))//当未读取文件尾标志16.{fputc(ch,fp2);//向file2.txt文件输出一个字符17.ch=fgetc(fp1);//再从file1.txt文件读入一个字符18.}19.fclose(fp1);20.fclose(fp2);21.return

0;22.}

运行结果student1234

验证:9.14文件的定位知识准备rewind函数和fseek函数【例9-7】有一个文件file.txt,请用fseek函数读取文件中的第7个和倒数第5个字符,打印该位置的字符。运行结果第7个字符:W倒数第5个字符:f

1.#include

<stdio.h>

2.int

main()

{

3.

FILE*fp=

fopen("D:\\study\\file.txt",

"w+");

4.

fprintf(fp,

"HelloWorld!Thisisatestfile.");

5.

6.

fseek(fp,

6,

SEEK_SET);

//移动到第7个字符位置

7.

char

c=

fgetc(fp);

8.

printf("第7个字符:%c\n",

c);

9.

10.

fseek(fp,

-5,

SEEK_END);

//移动到文件末尾前5个字符11.

c=

fgetc(fp);12.

printf("倒数第5个字符:%c\n",

c);13.

14.

fclose(fp);15.

return

0;16.}任务9实现库存数据文件管理(1)实现库存数据的文件存储功能(2)实现库存数据的文件读取功能(3)提供简单的用户界面任务实施:任务要求第1-5行:头文件包含和宏定义,其中第4行定义数据文件名,所有数据将保存到此文件。第7-50行:定义saveToFile()函数,主要功能为保存数据到文件,即将用户输入的商品数据以二进制格式保存到文件,先保存商品总数,再逐个保存每个商品的详细信息。第52-77行:定义了loadFromFile()函数,主要功能为从文件读取数据,从二进制文件中读取商品数据并显示到屏幕,读取顺序必须与保存顺序完全一致。第79-99行:为主函数部分,通过while(1)无限循环和switch()多分支结构,简单循环菜单,并支持数据保存、读取和退出。任务实施:代码说明任务9实现库存数据文件管理任务实施:代码实现

1.#include

<stdio.h>

2.#include

<stdlib.h>

3.

4.#define

FILENAME"inventory.dat"

5.#define

MAX_ITEMS3

6.

7.void

saveToFile()

{

8.

FILE*file=

fopen(FILENAME,

"wb")

;

9.if

(file==

NULL)

{

10.

printf("无法创建文件!\n");

11.

//

return;

12.

}

13.

14.

int

itemCount;

15.

printf("输入要保存的商品数量:");

16.

scanf("%d",

&itemCount);

17.

18.

if

(itemCount>

MAX_ITEMS)

{

19.

printf("数量超过最大限制!\n");

20.

fclose(file);

21.

return;

22.

}23.

24.

fwrite(&itemCount,

sizeof(int),

1,

file);

25.

int

i;

26.

for

(i=0;

i<itemCount;

i++)

27.

{

28.

int

id,

quantity;

29.

char

name[20];

30.

float

price;

31.

32.

printf("\n商品%d:\n",

i+

1);

33.

printf("输入ID:");

34.

scanf("%d",

&id);

35.

printf("输入名称:");

36.

scanf("%s",

name);

37.

printf("输入价格:");

38.

scanf("%f",

&price);

39.

printf("输入数量:");

40.

scanf("%d",

&quantity);

41.

42.

fwrite(&id,

sizeof(int),

1,

file);

43.

fwrite(name,

sizeof(char),

20,

file);

44.

fwrite(&price,

sizeof(float),

1,

file);

45.

fwrite(&quantity,

sizeof(int),

1,

file);

46.

}

47.

48.

fclose(file);

49.

printf("数据已保存到文件!\n");

50.

}

51.

52.

void

loadFromFile()

{

53.

FILE*file=

fopen(FILENAME,

"rb");

54.

if

(file==

NULL)

{

55.

printf("文件不存在或无法打开!\n");

56.

//return;

57.

}

58.

int

itemCount,i;

59.

fread(&itemCount,

sizeof(int),

1,

file);

60.

61.

printf("\n从文件读取的商品数据:\n");

62.

printf("ID\t名称\t\t价格\t数量\n");

任务9实现库存数据文件管理任务实施:代码实现

63.

printf("----------------------------------------\n");

64.

for

(i=0;

i<itemCount;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论