文中的源码都在这里哦!!!

文中的源码都在这里哦!!!

一、文件的基本概念

  • 一个文件通常是磁盘上一段命名的存储区

  • 磁盘文件(通常用的文件):指一组相关数据的有序集合,通常存储在外部介质(如磁盘)上,使用时才调入内存

  • 设备文件(与硬件有关的文件):在操作系统中把每一个与主机相连的输入、输出设备看作是一个文件,把它们的输入、输出等同于对磁盘文件的读和写。例如:键盘(标准输入文件)、屏幕(标准输出文件)

  • 以下说的是磁盘文件

(一)磁盘文件的存取过程

  • 磁盘文件,一般保存在硬盘、光盘、U盘等掉电不丢失的磁盘设备中,在需要时调入内存

  • 在内存中对文件进行编辑处理后,保存到磁盘中(内存只是文件的处理区,不是存储区)

  • 程序与磁盘之间交互,不是立即完成,系统或程序可根据需要设置缓冲区,以提高存取效率,延长磁盘寿命(在缓冲区进行暂时存储,直到存储的数据量达到一定的数量,不然存储一次打开一次磁盘,会缩短磁盘寿命)

(二)文件分类(重要)

1、物理上

  • 所有的磁盘文件都是二进制存储,以字节为单位进行顺序存储(空间是连续的)

2、逻辑上

  • 程序文件:有后缀名,主要用于存储程序代码

  • 数据文件:程序运行时读写的数据

  • 数据文件可分为ASCII文件(文本文件)二进制文件——C语言可识别的文件

  • 文本文件

  • 基于字符编码,常见编码有ASCII、UNICODE等,一般可以使用文本编辑器直接打开

  • 例如:数5678以ASCII存储形式为

    • ASCII码:00110101 00110110 00110111 00111000

    • 是每个字符的ASCII码值

    • 效率低,需要查表,但便于查看

  • 二进制文件

  • 基于值编码,根据应用指定某个值的意思

  • 把内存中的数据按其在内存中的存储形式原样输出到磁盘上

  • 例如:5678的存储形式为

    • 进制码:0001 0110 0010 1110

    • 读取效率很高,但是解译很麻烦,查看麻烦

3、两者的对比

文本文件 二进制文件
译码 编码基于字符定长,译码容易些 编码是变长的,译码难一些(不同的二进制文件格式,有不同的译码方式)
空间利用率 任何一个符号至少需要一个字节 用一个比特来代表一个意思(位操作)
可读性 通用的记事本工具就几乎可以浏览所有文本文件 需要一个具体的文件解码器

二、文件操作

  • C语言中不能直接操作文件,需要借助库函数对文件进行操作

  • 基本流程

  • 在使用文件前要调用打开函数将文件打开,得到文件指针fp

  • 然后调用各种有关函数,利用fp对文件进行具体处理(读或写)

  • 在文件用完时,及时调用关闭函数来关闭文件

  • C语言中所有的文件操作都围绕文件指针完成(只有通过文件指针,我们才能知道自己操作的是哪个文件),所以操作文件前必须定义一个文件指针指向我们将要操作的文件

(一)文件指针

  • 文件指针:指向文件的指针,可以指向文件的内存地址

  • 格式:FILE * 指针变量标识符

 // 由于文件类型已经在stdio.h头文件中有声明了,所以我们不需要另外声明,直接使用就行了FILE *fp = NULL;
  • FILE为大写,需要包含头文件<stdio.h>

  • FILE是系统使用typedef定义出来的有关文件信息的一种结构体类型,FILE结构体中含有文件名、文件状态和文件当前位置等信息(不需要关心)

  • c语言中有三个特殊的文件指针无需定义,打开可直接使用(在后续说明中会提到!!!)

  • stdin:标准输入。默认为当前终端(键盘),使用的scanf、getchar函数默认从此终端获得数据

  • stdout:标准输出。默认为当前终端(屏幕),使用的printf、puts函数默认输出信息到此终端

  • stderr:标准出错。默认为当前终端(屏幕),当我们程序出错或者使用perror函数时信息打印在此终端

(二)打开与关闭文件

  • 任何文件使用之前必须打开,使用后必须关闭

1、fopen打开一个文件

  • 格式:fp = fopen(文件名,文件打开方式)

  • 返回值:返回的是文件的起始地址,执行不成功返回NULL(需要在打开之后判断是否打开成功)

  • 文件名:要操作文件的名字,可包含路径

  • 文件路径 + 文件名主干 + 文件后缀

  • 文件的路径可以唯一标识文件的位置

  • 绝对路径:从根目录(盘符)开始的文件路径 + 文件名 + 文件扩展名(文件类型)

  • 相对路径:相对于当前目录,从当前目录开始访问到某一文件的路径

  • 打开方式:读、写、二进制、文本(与文件的存储方式无关,与操作系统有关)

  • r:以只读方式打开文件。文件不存在返回NULL;文件存在返回文件指针,进行后续的读操作

  • w:以只写方式打开文件。文件不存在指定文件名创建此文件;文件存在则清空文件内容,进行写操作;文件打不开,返回NULL

  • a:以追加方式打开文件。文件不存在,以指定文件名创建此文件(同w);若文件存在,从文件的结尾处进行写操作

  • +:可读可写

  • b:以二进制的方式打开文件

  • t:以文本的方式打开文件(省略!!!)

  • 不是很重要,了解一下就行
  • 在windows平台下,当读取文件的时候,系统会将所有的"\r\n"转换成"\n";当写入文件的时候,系统会将"\n"转换成"\r\n"写入
  • 在Unix/Linux平台下,“文本”与“二进制”模式没有区别。\r\n作为两个字符原样输入输出
  • 打开方式的组合形式

模  式

功   能

r或rb

以只读方式打开一个文本文件(不创建文件)

w或wb

以写方式打开文件(使文件长度截断为0字节,创建一个文件)

a或ab

以添加方式打开文件,即在末尾添加内容,当文件不存在时,创建文件用于写

r+或rb+

以可读、可写的方式打开文件(不创建新文件)

w+或wb+

以可读、可写的方式打开文件

(使文件长度为0字节,创建一个文件)

a+或ab+

以添加方式打开文件,打开文件并在末尾更改文件(如果文件不存在,则创建文件)

  • 顺序读写文件:文件指针会从文件指针当前位置顺序读写文件,打开文件时,文件指针默认指向文件的开头

2、fclose关闭文件

  • 格式:fclose(文件指针);

  • 正常执行则返回0,不成功则返回-1(EOF)

3、练习

  • 以只读、文本方式打开当前路径下一个叫test.txt文件

  • 以只写、二进制方式打开同一个文件

  • 以追加(a)、文本的方式打开同一个文件

  • 同时以读/写、二进制方式打开同一个文件,要求若文件不存在,提示出错

  • 同时以读/些、文本方式打开同一个文件,要求若文件不存在,创建此文件

  • 若打开成功则关闭相应的文件

void test1()
{FILE *fp = NULL; fp = fopen("tset.txt", "r"); // 只读、文本fp = fopen("test.txt","wb"); // 只写、二进制fp = fopen("test.txt","a"); // 追加、文本fp = fopen("tset.txt", "rb+"); // 可读可写、二进制、不存在报错fp = fopen("test.txt","w+"); // 可读可写、文本、不存在创建if(fp != NULL) // 打开成功则关闭相应的文件{fclose(fp); }
}

  • 对文件操作最常用的是:“读”和“写”

  • C语言提供了多种对文件读写的函数

  • 字节读写函数:  fgetc和fputc

  • 字符串读写函数:fgets和fputs

  • 数据块读写函数:fread和fwrite

  • 格式化读写函数:fscanf和fprintf

  • 以上函数可完成对文件内容的顺序读写


(三)文件的字节读写(单个字符的输入输出)

1、fgetc:字节读操作

  • 格式:ch = fgetc(fp); 

  • 说明

  • 从指定文件读取一个字节赋给ch(以“读”或“读写的方式”打开文件)

  • 读取文本文件,读到文件结尾返回EOF(EOF是在stdio.h文件中定义的符号常量,值为-1)

  • 二进制文件,读到文件结尾,使用feof判断结尾(后面会讲)

2、读操作示例

  • 如果本地没有创建相应的文件,会报错如下所示

  • 事先在本地创建a.txt,文件内容为 hello file

  • 文件输出:buf = hello file

void test2()
{char buf[128] = "";int i = 0;FILE* fp = NULL;// 1、使用fopen打开一个文件,获得文件指针fp = fopen("a.txt", "r");if (fp == NULL) // 以只读的形式打开文本,当前目录下没有该文本,输出错误信息,然后退出{perror("fopen");return;}// 2、对文件的操作fgetcwhile (1){// fgetc调用一次 读取到一个字节buf[i] = fgetc(fp);if (buf[i] == EOF) // EOF表示已经到文件末尾{break;}i++;}printf("buf = %s\n", buf);// 3、关闭文件fclose(fp);
}

3、fputc:字节的写操作

  • 格式:fputc(ch,fp);

  • 说明

  • 把一个ch变量中的值(1个字节)写到指定的文件

  • 如果输出成功,则返回输出的字节;如果输出失败,则返回一个EOF

4、写操作示例

void test3()
{char buf[128] = "";int i = 0;FILE* fp = NULL;fp = fopen("b.txt", "w"); // 没有就创建if (fp == NULL){perror("fopen");return;}// 使用fputc进行文件的数据写入printf("请输入要写入文件的字符串:");fgets(buf, sizeof(buf), stdin); // 会获取换行符buf[strlen(buf) - 1] = 0; // 去掉键盘输入的换行符// 将字符串buf中的元素 逐个写入文件中while (buf[i] != '\0'){fputc(buf[i], fp);i++;}fclose(fp);
}

5、练习:从a.txt读取文件内容写入到b.txt

void test4()
{FILE *fp1 =NULL;FILE *fp2 =NULL;// 以只读的方式打开a.txtfp1 = fopen("a.txt","r");if(fp1 == NULL){perror("fopen");return;}// 以只写的方式打开b.txtfp2 = fopen("b.txt","w");if(fp2 == NULL){perror("fopen");return;}// 从fp1中每读取一个字节写入到fp2中while(1){char ch;// 读ch = fgetc(fp1);if(ch == EOF) // 已经读到文件末尾break;// 写fputc(ch,fp2);}fclose(fp1);fclose(fp2);return;
}

(四)字符串的输入输出(文件的字符串读写)

1、fputs:往文件中写入一个字符串

  • 格式:fputs("china", fp);

  • 说明

  • 向指定文件写入一个字符串

  • 第一个参数可以是字符串常量、字符数组、字符指针

  • 字符串末尾的'\0'不会写进文件

void test5()
{// 指针数组char *buf[]={"窗前明月光\n","疑似地上霜\n","举头望明月\n","低头思故乡"};int n = sizeof(buf)/sizeof(buf[0]);FILE *fp = NULL;int i=0;fp = fopen("c.txt", "w");if(fp == NULL){perror("fopen");return;}for(i=0;i<n; i++){fputs(buf[i], fp);}fclose(fp);
}

2、fgets:从文件中获取字符串

  • 格式:fgets(str, n, fp);

  • 说明

  • 功能:从fp指向的文件中读取n-1个字符,在读取n-1个字符之前遇到换行符或EOF,提前结束读取并在最后加一个’\0’

  • str:存放数据的首地址

  • 返回值:成功读取则返回读到字符串的首元素地址,失败则返回NULL

  • 可以读取换行符

  • 用来获取文件一行的数据

void test6()
{char buf[128] = "";FILE* fp = NULL;char* path = "c.txt"; // path指向文件名为"c.txt"的地址fp = fopen(path, "r");if (fp == NULL){perror("fopen");return;}while (fgets(buf, sizeof(buf), fp)){printf("%s\n", buf);}fclose(fp);
}

3、综合示例

void test7()
{FILE* fp = NULL;char str[10] = "\0";fp = fopen("test1.txt", "w");fputs("XYZ123*#!", fp); // 将字符串"XYZ123*#!"写入文件指针fp指向的当前文件位置fclose(fp);fp = fopen("test1.txt", "r+");fgets(str, 8, fp); // 从文件指针fp指向文件的当前位置读取7个字符存入字符数组str中// 获取字符的长度会比参数给定的长度小1个,因为需要用于存储'\0'puts(str);fclose(fp);
}

4、练习:从一个文件中读取一个字符串,输出到另一个文件

void test8()
{FILE* fp_r, * fp_w; // 文件读写指针char str[100] = "";fp_r = fopen("src.text", "r+");if (fp_r == NULL) // 判断文件是否正常打开{perror(fopen);return;}fp_w = fopen("dest.text", "w+");if (fp_w == NULL){perror(fopen);return;}// 文本输入输出fgets(str, 20, fp_r);puts(str);fputs(str, fp_w);// 键盘输入,屏幕输出fgets(str, 100, stdin);fputs(str, stdout);fclose(fp_r);fclose(fp_w);return 0;
}

(五) 文件块的读写(以二进制的形式读写数据)

1、fwrite:将数据块写入到文件中

  • 格式:fwrite(buffer,size,count,fp);

  • 说明

  • buffer:指向存储数据空间的首地址的指针

  • size:一次性读取数据块大小

  • count:要读取的数据块的个数

  • fp:指向要进行写操作的文件指针

  • 返回实际读写的数据块数---count(不是总数据大小哦!!!)

void test08()
{// 定义一个结构体,英雄名、喜爱程度、玩的次数HERO hero[] = {{"盾山",100, 150},{"牛魔",80, 20},{"鲁班大师",95, 85},{"东皇",100, 90}};int n = sizeof(hero) / sizeof(hero[0]);FILE* fp = NULL;fp = fopen("hero.txt", "w");if (fp == NULL){perror("fopen");return;}// fwrite将内存的数据原样的输出到文件中// 写入文件的数据不便于用户查看,但是不会影响程序的读fwrite(hero, sizeof(HERO), n, fp);fclose(fp);
}
  • 查看的时候发现和自己写入的内容不一样,这就是文件块的特点保存的快,但是查看比较麻烦 

2、fread:从文件中读取数据块

  • 格式:fread(buffer,size,count,fp);

  • 参数与fwrite一样

void test10()
{HERO hero[4];int i = 0;FILE* fp = NULL;fp = fopen("hero.txt", "r");if (fp == NULL){perror("fopen");return;}fread(hero, sizeof(HERO), 4, fp); // 结构体数组中有四组数据for (i = 0; i < 4; i++){printf("英雄姓名:《%s》,喜爱程度:《%d》,玩的次数:《%d》\n", \(hero + i) -> name, (hero + i) ->Is_Love, (hero + i) ->Play_NUm);}fclose(fp);
}

3、综合示例

void test11()
{FILE* fp = NULL;int arr[6] = { 1, 2, 3, 4, 5, 6 };fp = fopen("test3.txt", "wb"); // 只写的形式打开二进制文本fwrite(arr, sizeof(int), 6, fp); // 把整型数组arr中6个大小为int类型的数据写入文件指针fp所指向的文件当前位置fclose(fp);int arr2[6] = { 0 };fp = fopen("test3.txt", "rb");fread(arr2, sizeof(int), 6, fp); // 从文件指针fp所指向文件的当前位置读取6个整型大小的数据放入数组arr2中for (int i = 0; i < 6; i++)printf("%d\t", arr2[i]);putchar('\n');fclose(fp);
}

4、练习:从键盘输入一个结构体数组数据,输出到文件,再读入并显示

void test12()
{struct stu boya[10], boyb[2];FILE* fp = NULL;int i = 0;fp = fopen("test12.txt", "wb+");if (fp == NULL){perror(fopen);return;}printf("请输入数据:\n");for (; i < 2; i++){scanf("%s %d %d", boya[i].name, &boya[i].num, &boya[i].age);}fwrite(boya, sizeof(boya), 2, fp); // 学生信息写入文件rewind(fp); // 重新将文件指针指向开头fread(boyb, sizeof(boyb), 2, fp);for (i = 0; i < 2; i++){printf("%s %d %d", boyb[i].name, boyb[i].num, boyb[i].age);}fclose(fp);
}

(六)文件的格式化操作(格式化输入和输出函数)

  • 格式化输入输出:以什么格式输入的就以什么格式输出

  • 针对文件块查看不便的问题,通过格式化输入输出的方法

1、fprintf:格式化写操作

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

void test13()
{HERO hero[] = {{"盾山",100, 150},{"牛魔",80, 20},{"鲁班大师",95, 85},{"东皇",100, 90}};int n = sizeof(hero) / sizeof(hero[0]);FILE* fp = NULL;int i = 0;fp = fopen("hero.txt", "w");if (fp == NULL){perror("fopen");return;}for (i = 0; i < n; i++){fprintf(fp, "英雄:%s 喜爱程度:%d 玩的次数:%d\n", hero[i].name, hero[i].Is_Love, hero[i].Play_NUm);}fclose(fp);
}

2、fscanf:格式化读操作

  • 格式:fscanf(文件指针, 格式化字符串, 输入列表);

void test14()
{HERO hero[4];int i = 0;FILE* fp = NULL;fp = fopen("hero.txt", "r");if (fp == NULL){perror("fopen");return;}for (i = 0; i < 4; i++){fscanf(fp, "英雄:%s 喜爱程度:%d 玩的次数:%d\n", hero[i].name, &hero[i].Is_Love, &hero[i].Play_NUm);}for (i = 0; i < 4; i++){printf("%s %d %d\n", hero[i].name, hero[i].Is_Love, hero[i].Play_NUm);}fclose(fp);
}

3、综合示例

  • 优点:对磁盘文件读写使用方便,容易理解,直观的查看

  • 缺点:在输入时将ASCII码转换成二进制,在输出时将二进制转为字符,花费时间较多

struct student { // 学生结构体int id;char name[20];char sex[4];int age;float score;
};
void test15()
{FILE* fp = NULL;struct student S1 = { 1, "小明", "男", 18, 90.5 }, S2;fp = fopen("test15.txt", "w");fprintf(fp, "%d %s %s %d %f\n", S1.id, S1.name, S1.sex, S1.age, S1.score); // 以指定的格式把数据写入文件指针fp所指向的文件中fclose(fp);fp = fopen("test15.txt", "r");fscanf(fp, "%d %s %s %d %f\n", &S2.id, S2.name, S2.sex, &S2.age, &S2.score); // 以指定的格式从文件指针fp所指向的文件中读取一些数据放入结构体变量S2中fclose(fp);
}

(七)格式化输入输出与文件块对比

  • 文件拷贝用文件块read和fwrite函数,速度快,查看不方便

  • 文件打印输出查看用fprintf和fcsanf函数,不在乎时间,需要的是直观可看

  • 在内存与磁盘频繁交换数据的情况下,最好不用fprintf和fcsanf函数,而使用fread和fwrite函数

C语言---14文件操作---01文件内容的顺序读写相关推荐

  1. 文件操作01 - 零基础入门学习C语言60

    第十一章:文件操作01 让编程改变世界 Change the world by program C文件概述 所谓"文件"是指一组相关数据的有序集合.这个数据集有一个名称,叫做文件名 ...

  2. python对文件的操作都有什么_python中文件操作的相关内容总结(附示例)

    本篇文章给大家带来的内容是关于python中文件操作的相关内容总结(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1. 文件操作介绍 说到操作文件我们肯定会想到流,文件的操 ...

  3. 【C 语言】文件操作 ( 按照单个字符的方式读写文件 | fgetc 函数 | fputc 函数 )

    文章目录 一.文件名路径设置 二.文件打开方式 三.fputc 函数 | 按照字符方式写文件 1.fputc 函数 2.代码示例 四.fgetc 函数 | 按照字符方式读文件 1.fgetc 函数 2 ...

  4. c语言打开关闭文件的顺序,C语言1-文件概述、文件的打开与关闭、顺序读写数据文件(1).docx...

    C语言程序设计教案 章节名称 文件概述.文件的打开与关闭.顺序读写数据文件(1) 授课类型 □理论 □实验 ?理实一体 □实训 □实习 班级 地点 周次 星期 节次 授课进度 ?符合 □超前 □滞后 ...

  5. C++ 学习笔记之——文件操作和文件流

    1. 文件的概念 对于用户来说,常用到的文件有两大类:程序文件和数据文件.而根据文件中数据的组织方式,则可以将文件分为 ASCII 文件和二进制文件. ASCII 文件,又称字符文件或者文本文件,它的 ...

  6. python关闭读写的所有的文件-Python文件操作:文件的打开关闭读取写入

    Python文件操作:文件的打开关闭读取写入 一.文件的打开关闭 Python能以文本和二进制两种方式处理文件,本文主要讨论在Python3中文本文件的操作. 文件操作都分为以下几个步骤: 1.打开文 ...

  7. .NET基础-11-ArrayList|Hashtable|File文件操作|Dircetioy文件夹操作|Path路径操作

    集合 ArrayList与Hashtable应为存在拆箱与装箱,所以性能不怎么好,尽量不要使用,而使用泛型集合 可以使用下面的方式输出所消耗的时间 //ArrayList arl = new Arra ...

  8. python以写模式打开的文件无法进读操作_Python文件操作:文件的打开关闭读取写入...

    Python文件操作:文件的打开关闭读取写入 一.文件的打开关闭 Python能以文本和二进制两种方式处理文件,本文主要讨论在Python3中文本文件的操作. 文件操作都分为以下几个步骤: 1.打开文 ...

  9. 今天的码农女孩做了关于文件操作和文件拖拽的笔记 2022/1/21

    文件操作和文件拖拽 文件操作: js有两种机制:一个是事件机制,一个是io机制 文件操作对象: Blob通过二进制数据读取 file读取单个文件对象 fileList读取多个文件对象 fileRead ...

最新文章

  1. php 获取key的位置,PHP使用腾讯地图获取指定地址坐标:创建key(图文+视频)
  2. 麦克风阵列降噪_黄鹂智声降噪耳机E100u,与喧嚣说再见
  3. x86 vs x64
  4. linux内核开发_Linux 内核的代码仓库管理与开发流程简介
  5. linux dump_stack
  6. Typora 常用技巧
  7. linux将日期和日历信息追加到文件中_Linux常用指令
  8. 连通区域的边界点程序
  9. bzoj1597 土地购买
  10. int范围内数字的英文读法
  11. 最小二乘拟合问题求解算法(含python代码)
  12. Alphabet执行董事长明年1月辞职,谷歌高管大洗牌
  13. 中国大学MOOC所有课程信息爬虫(课程ID、学校简称、课程名字、教师、学校全称、学生人数、学生人数、评价人数、平均评价)
  14. 【4500字归纳总结】一名软件测试工程师需要掌握的技能大全
  15. 百度热力图颜色说明_揭秘!看完徐州城市人口热力图,你就知道该在哪儿买房了...
  16. 单片机 AD/DA数模转换
  17. linux红帽子认证费用RHCT,关于RHCE和RHCT认证
  18. 记:解决 Weditor 页面元素坐标定位不到、不准确的问题
  19. 王占祥:公募基金券商交易模式
  20. arr的push,pop,slice.....各种使用方法详细介绍

热门文章

  1. 流量的秘密—Google Analytics网站分析与优化技巧(第2版)
  2. 通过浏览器无法访问Hadoop管理页面
  3. 去水印小程序好做吗?赚钱吗?
  4. 乘风破浪程序猿,拒绝原地踏步!
  5. 计算机IP地址pin,打印机的ip地址在机身上哪里,打印机的pin在哪看
  6. 310569138 294609417 297440781 猪八戒上的骗子
  7. ElasticSearch:为中文分词器增加对英文的支持(让中文分词器可以处理中英文混合文档)(转)
  8. CC00388.CloudKubernetes——|KuberNetesCI/CD.V26|——|Jenkins.v06|自动构建Java应用.v06|报错处理|
  9. 谱聚类(Spectral Clustering)算法介绍
  10. cpu排行计算机专业,cpu性能天梯图,详细教您电脑cpu排行榜