C语言文件操作(下)(28)

文章目录

  • 前言
  • 一、文件的打开和关闭
    • 打开
      • 打开模式
      • 相对路径和绝对路径
    • 关闭
  • 二、文件操作正确流程
  • 三、文件顺序读写函数
    • fopen
    • fclose
    • fputc
    • fgetc
    • fputs
    • fgets
    • fprintf
    • fscanf
    • sprintf
    • sscanf
    • fwrite
    • fread
  • 四、文件随机读写函数
    • fseek
    • ftell
    • rewind
  • 五、文件读取结束时候的判断
    • feof
    • ferror
    • 具体例子
  • 总结


前言

  承接上文,正文开始!


一、文件的打开和关闭

打开

 如果需要对文件进行一些读写操作,那么首先就需要先打开文件,在使用完以后关闭文件,所以最基本是打开文件和关闭文件
ANSIC规定使用fopen函数来打开文件,fclose来关闭文件

打开文件FILE* fopen(const char* filename, const char* mode);
关闭文件FILE* fclose(FILE* stream);

打开模式

mode表示文件的打开模式,下面都是文件的打开模式:

文件打开方式含义及如果指定⽂件不存在
“r”(只读)为了输入数据,打开一个已经存在的文本文件,出错
“w”(只写)为了输出数据,打开一个文本文件,建立一个新的文件
“a”(追加)向文本文件尾添加数据,建立一个新的文件
“rb”(只读)为了输入数据,打开一个二进制文件 ,出错
“wb”(只写)为了输出数据,打开一个二进制文件 ,建立一个新的文件
“ab”(追加)向一个二进制文件尾添加数据 ,建立一个新的文件
“r+”(读写)为了读和写,打开一个文本文件,出错
“w+”(读写)为了读和写,建议一个新的文件 ,建立一个新的文件
“a+”(读写)“a+”(读写),建立一个新的文件
“rb+”(读写)为了读和写打开一个二进制文件,出错
“wb+”(读写)为了读和写,新建一个新的二进制文件,建立一个新的文件
“ab+”(读写)打开一个二进制文件,在文件尾进行读和写,建立一个新的文件

使用上面的模式说明符,文件将作为文本文件打开。为了将文件作为二进制文件打开,模式字符串中必须包含“b”字符。这个附加的“b”字符可以附加在字符串的末尾(从而形成以下复合模式:“rb”、“wb”、“ab”、“r+b”、“w+b”、“a+b”),也可以插入在“+”符号之前(“rb+”、“wb+”、“ab+”)

在某些库实现中,使用更新模式打开或创建文本文件可能会视为二进制文件

来举几个例子:
一、我们要以文本形式打开一个名叫data.txt的文件,将要对其进行输入操作:

	//注:data.txt文件必须存在,不然打开文件失败,fopen函数会返回一个空指针FILE* pf = fopen("data.txt", "r");

二、若我们要以二进制打开一个名叫data.bin的文件,将要对其进行输出操作:

	//注:data.bin文件若存在,将销毁文件原有内容,再对其进行输出;data.bin文件若不存在,系统将主动创建一个名叫data.bin的文件FILE* pf = fopen("data.bin", "wb");

所以我们一般要检测一下文件指针的有效性:

	FILE* pf = fopen("data.txt", "r");if (pf == NULL){printf("%s\n", strerror(errno));return 1;//失败返回}//使用...

相对路径和绝对路径

填写fopen函数的第一个参数的时候,如果我们要打开的文件与我们正在运行的源代码在同级目录下(以打开data.txt文件为例),那么我们应该这样写:

	FILE* pf = fopen("data.txt", "r");//同级

 但是如果我们想要打开的文件与当前运行的源代码不在同一级目录下呢?这就涉及到相对路径和绝对路径了~

  1. 当待打开的文件位于正在运行的源代码的上一级时:
	FILE* pf = fopen("../data.txt", "r");//上一级
  1. 当待打开的文件位于正在运行的源代码的下一级时:
	//注:这里data.txt文件在Debug文件内,Debug文件与正在运行的源代码在同级目录下FILE* pf = fopen("Debug/data.txt", "r");//下一级

 而有人可能觉得相对路径的方法比较麻烦(可能还要去数目标文件与源文件相差的级数),绝对路径就没那么麻烦了,绝对路径就直接写出目标文件的完整路径即可:

	//注:文件的路径原本为"D:\code\File_function\File_function\data.txt",//但是为了防止字符串中的’\‘及其后面的字符被整体视为为转义字符,所以需要在每个’\‘后面再加一个’\’FILE* pf = fopen("D:\\code\\File_function\\File_function\\data.txt", "r");

关闭

 与动态开辟内存空间时一样,当我们打开文件时,会在内存中开辟一块空间,如果我们打开该文件后不关闭,那么这个空间会一直存在,一直占用那块内存空间,所以当我们对一个文件的操作结束时,一定要记住将该文件关闭。这就需要用到fclose函数来关闭文件:

	int fclose(FILE *stream);

 我们如果要关闭一个文件,那么直接将该文件的文件指针传入fclose函数即可,fclose函数如果关闭文件成功会返回0。与free函数一样,当我们调用完fclose函数将文件关闭后,我们也要将指向文件信息区的指针置空,避免该指针变成野指针

	fclose(pf);//关闭pf指向的文件pf = NULL;//及时置空

二、文件操作正确流程

  知道了如何打开文件和关闭文件,也就相当于知道了如何进入和如何出去,所以当我们要对一个文件进行操作的时候,正确的流程应该是这样的:

#include <stdio.h>
#include <string.h>
#include <errno.h>int main()
{//打开文件FILE* pf = fopen("data.txt", "r");if (pf == NULL)//检测指针有效性{printf("%s\n", strerror(errno));//错误提醒return 1;//失败返回}//对文件进行一系列操作//...//关闭文件fclose(pf); //关闭pf指向的文件pf = NULL;//及时置空return 0;
}

三、文件顺序读写函数

fopen

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

功能:打开其名称在参数 filename 中指定的文件,并将其与流相关联,该流可在将来的操作中通过返回的 FILE指针进行标识

返回值:如果文件成功打开,该函数将返回指FILE对象的指针,该对象可用于在将来的操作中标识流,如果文件没有成功打开,则将返回NULL

允许对流执行的操作以及如何执行这些操作由 mode 参数定义

fclose

int fclose(FLIE *stream)

功能:关闭与流关联的文件并取消关联

与流关联的所有内部缓冲区都将与其解除关联并刷新:写入任何未写入的输出缓冲区的内容,并丢弃任何未写入输入缓冲区的内容。(更新缓冲区)

返回值:流关闭成功,则返回0。关闭失败,返回EOF

fputc

在这里插入图片描述
功能:将字符写入流并推进位置指示器,然后自动前进1。适用于所有输入流(字符输入到流中)

参数部分:character->将要写入的字符的整型提升,写入时,该值在内部转换为无符号字符;stream->指向标识输出流的FILE对象指针

返回值:成功,将返回写入的字符。发生写入错误,则返回EOF并设置错误指示符(ferror)

int main()
{FILE* pf = fopen("test1.txt", "w");if (pf == NULL){perror("fopen fail!!!");return 1;}fputc('d', pf);fputc('e', pf);fclose(pf);pf = NULL;return 0;
}

在这里插入图片描述

请注意,对于stream可以是文件流也可以是标准流
那么现在,使用fputc将A ~Z个字符输入到指定文件和显示器中,该怎么办?

fgetc

在这里插入图片描述
功能:字符输入函数,从流中获得字符,返回指定流的内部文件位置指示符当前指向的字符,内部文件位置指示器将前进到下一个字符

返回值:成功后,将返回字符读取(进行整型提升)。如果失败则,返回EOF

int main()
{FILE* pf = fopen("test1.txt", "r");if (pf == NULL){perror("fopen fail!!!");return;}	char ch;//ch用于接收fgetc从流中获得的字符ch = fgetc(pf);printf("%c", ch);ch = fgetc(pf);printf("%c", ch);fclose(pf);pf = NULL;return 0;
}

那么现在,我想进行文档的拷贝,这又该怎么办?

fputs

在这里插入图片描述
功能:文本行输入函数,将str指向的字符串写入流中,从指定的地址开始复制,直到结束标志\0(\0’字符不会复制到流中)

返回值:成功,返回一个非负值,失败,则返回EOF

int main()
{FILE * pf = fopen("test1.txt", "w");if (pf == NULL){perror("fopen fail!!!");return;}	fputs("hellow world", pf); //将字符串输入到文件流中fputs("hellow world", stdout); //将字符串输入到输出流中(打印到屏幕上)fclose(pf);pf = NULL;return 0;
}

fgets

在这里插入图片描述
功能:文本行输入函数,从流中获得字符串,直到读取到num-1个字符或者在达到换行符或文件末尾(前者为准)。换行符(\n)会使fgets停止,但函数将其视为有效字符,并包含在复制到str的字符串中,在将字符复制到str之后,会自动添加\0,导致只能读取num-1字符

参数部分上:str->指向复制字符串读取到char数组的指针(这里提前开辟好数组)、num->复制到str中的最大字符数(包括‘\0’字符-字符串)、返回值->成功,返回str指针,失败,返回EOF

返回值:成功,返回str指针,失败,返回EOF

int main()
{FILE* pf = fopen("test1.txt", "r");if (pf == NULL){perror("fopen fail!!!");return;}char str[1000]="xxxxxxx";fgets(str, 7, pf);printf("%s", str);fclose(pf);pf = NULL;return 0;
}

fprintf

在这里插入图片描述
功能:按格式化数据写入流,如果format包含格式说明符(%开头的子序列),则格式化format后面的其他参数并将其插入到生成的字符串中,代替其各自的说明符,根据格式说明符顺序,匹配不同类型对应的数据,输入到text1.txt中去

返回值:成功,返回写入字符总数,失败,则返回负数

struct S
{char str[1000];int i;float f;
};int main()
{struct S s={"zhangsan", 100, 4.3};FILE* pf = fopen("test1.txt", "w");if (pf == NULL){perror("fopen fail!!!");return 1;}fprintf(pf,"%s %d %f", s.str, s.i, s.f);fclose(pf);pf = NULL;return 0;
}

fscanf

在这里插入图片描述
功能:从流中读取数据,并根据格式将其存储到其他参数指向的位置,该对象由格式化字符串的相应格式说明符指示,根据格式说明符顺序,匹配text1.txt对应的数据,输入到对应的数据变量中

返回值:成功后,该函数返回已成功填充的参数列表的项数,失败,EOF

struct S
{char str[1000];int i;float f;
};int main()
{struct S s = {0};FILE* pf = fopen("test1.txt", "r");if (pf == NULL){perror("fopen fail!!!");return 1;}	fscanf(pf, "%s %d %f", s.a, &(s.p), &(s.pa));printf("%s %d %f", s.a, s.p, s.pa);fclose(pf);pf = NULL;return 0;
}

sprintf

在这里插入图片描述
功能:从字符串中读取格式化数据(将字符数组中的字符串按照格式说明符转换为对应的格式化数据)

sscanf

在这里插入图片描述
功能:将格式化数据写入字符串(格式化数据转换为字符串存放在字符数组中)

// sprintf和sscanf的实际运用
int main()
{//将格式化的数据转换为字符串存放在p数组中struct S s = { "zhangsan",100,4.3 };char p[1000] = { 0 };sprintf(p, "%s %d %f", s.a, s.p, s.pa);printf("%s\n", p);//从p这个字符串中提取格式化的数据(用p数组中的数据,为结构体t成员赋值)struct S t = {0};sscanf(p, "%s %d %f", t.a, &(t.p), &(t.pa));printf("%s %d %lf", s.a, s.p, s.pa);return 0;
}

fwrite

在这里插入图片描述
功能:二进制输出,将 count 元素数组(每个元素的大小为 size bytes)从 ptr 指向的内存块写入流中的当前位置

返回值:成功将返回写入元素个数,如果此数字与 count 参数不同,则写入错误会阻止函数完成,如果 size 或 count 为零,则函数返回零,错误指示器保持不变

int main()
{FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件if (pf == NULL){perror("fopen fail!!!");return;}int nums[] = { 1,2,3,4,5,6,7 };fwrite(nums, sizeof(int), 10, pf);fclose(pf);pf = NULL;return 0;
}

请注意,这里是通过二进制的形式写入文本文件中,如果想要看懂输入的数据,可以在打开方式选择二进制编辑器或者使用fread函数读取出来

fread

在这里插入图片描述
功能:二进制输入,从流中读取 count 元素的数组,每个元素的大小为 bytes,并将它们存储在 ptr 指定的内存块中

返回值:成功将返回写入实际元素个数,如果此数字与 count 参数不同,则表示读取时发生读取错误或达到文件末尾,如果 size 或 count 为零,则该函数返回零, ptr 指向的流状态和内容保持不变

如果实际文件中只有7个字符,count是14,那么读到7给字符就结束(返回值 < count就返回)

int main()
{FILE* pf = fopen("test1.txt", "rb");//打开一个二级制文件if (pf == NULL){perror("fopen fail!!!");return;}//int nums[] = { 1,2,3,4,5,6,7 };//fwrite(nums, sizeof(int), 7, pf);//读取二进制存放的信息int nums[10] = { 0 };fread(nums, sizeof(int), 10, pf);for (int i = 0; i < 10; i++){printf("%d ", nums[i]);}fclose(pf);pf = NULL;return 0;
}

四、文件随机读写函数

fseek

在这里插入图片描述
功能:重新定位流位置指示器,根据文件指针的位置和偏移量来定位文件指针

返回值:成功,返回零,失败,返回非零值

注意,对于二进制文件:要从原点偏移的字节数,对于文本文件:零或 ftell 返回的值

对于参数origin

  1. SEEK_SET :文件开头
  2. SEEK_CUR :文件指针的当前位置
  3. SEEK_END: 文件末尾
int main()
{FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件if (pf == NULL){perror("fopen fail!!!");return 1;}fputs("This is an apple", pf);fseek(pf, 3, SEEK_SET);fputs("sam", pf);fseek(pf, -3, SEEK_END);//文件指针往前走fputs("xxx", pf);fclose(pf);pf = NULL;return 0;
}

在这里插入图片描述

ftell

在这里插入图片描述
功能:返回流的位置指示器的当前值(返回文件指针相对于起始位置的偏移量 )

返回值:对于二进制流,这是从文件开头开始的字节,对于文本流,数值可能没有意义

int main()
{FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件if (pf == NULL){perror("fopen fail!!!");return 1;}fputs("This is an apple", pf);fseek(pf, 0, SEEK_END);int size = ftell(pf);printf("%d", size); //size == 16,源头到参考位置的字节数fclose(pf);pf = NULL;return 0;
}

rewind


功能:让文件指针的位置回到文件的起始位置

int main()
{FILE* pf = fopen("test1.txt", "wb");//打开一个二级制文件if (pf == NULL){perror("fopen fail!!!");return 1;}fputs("This is an apple", pf);fseek(pf, 0, SEEK_END);rewind(pf);int size = ftell(pf);printf("%d", size);fclose(pf);pf = NULL;return 0;
}

五、文件读取结束时候的判断

feof

在这里插入图片描述
功能:在文件读取结束后,判断是否是因为遇到文件末尾而结束,即看返回值是否是EOF

ferror

在这里插入图片描述
功能:在文件读取结束后,判断是否是因为遇到错误而结束

具体例子

牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束

  1. 文本文件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
    例如:fgetc 判断是否为 EOF ,fgets 判断返回值是否为NULL
  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数
    例如:fread判断返回值是否小于实际要读的个数
//文本文件
#include <stdio.h>
#include <stdlib.h>int main(void)
{int c; // 注意:int,非char,要求处理EOFFILE* fp = fopen("test.txt", "r");if (!fp) {perror("File opening failed");return EXIT_FAILURE;}//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOFwhile ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环{putchar(c);}//判断是什么原因结束的if (ferror(fp))puts("I/O error when reading");else if (feof(fp))puts("End of file reached successfully"); // 输出这个fclose(fp);fp = NULL;return 0;
}
//二进制文件
#include <stdio.h>
#include <stdlib.h>enum { SIZE = 5 };
int main(void)
{double a[SIZE] = { 1.,2.,3.,4.,5. };FILE* fp = fopen("test.bin", "wb"); // 必须用二进制模式fwrite(a, sizeof * a, SIZE, fp); // 写 double 的数组fclose(fp);double b[SIZE];fp = fopen("test.bin", "rb");size_t ret_code = fread(b, sizeof * b, SIZE, fp); // 读 double 的数组if (ret_code == SIZE) {puts("Array read successfully, contents: "); // 输出这个for (int n = 0; n < SIZE; ++n) printf("%f ", b[n]);putchar('\n');}else { // error handlingif (feof(fp))printf("Error reading test.bin: unexpected end of file\n");else if (ferror(fp)) {perror("Error reading test.bin");}}fclose(fp);fp = NULL;return 0;
}

总结

  文件操作,这篇我写得应该算是不太好,暂且将就一下吧~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/440618.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Mysql锁机制解读(敲详细)

目录 锁的概念 全局锁 表级锁 表锁 元数据锁 意向锁 锁的概念 全局锁 表级锁 表锁 元数据锁 主要是对未提交事务&#xff0c;修改表结构造成表结构混乱&#xff0c;进行控制。 在不涉及表结构变化的情况下,元素锁可以忽略。 意向锁 避免有行级锁影响加表级锁&#xff0…

openpnp - 吸嘴校正失败的opencv参数分析

文章目录 openpnp - 吸嘴校正失败的opencv参数分析概述笔记阶段验证 - N2吸嘴校验完NT1NT2 阶段验证 - 底部相机高级校验完NT1NT2 参数比对保存 “阶段验证 - N2吸嘴校验完” 的NT1/NT2图像重建参数检测环境NT1ok的3个参数值NT1err的3个参数值NT2ok的3个参数值NT2err的3个参数值…

黑马JavaWeb开发跟学(九)MyBatis基础操作

黑马JavaWeb开发跟学九.MyBatis基础操作 1. Mybatis基础操作1.1 需求1.2 准备1.3 删除1.3.1 功能实现1.3.2 日志输入1.3.3 预编译SQL1.3.3.1 介绍1.3.3.2 SQL注入1.3.3.3 参数占位符 1.4 新增1.4.1 基本新增1.4.2 主键返回 1.5 更新1.6 查询1.6.1 根据ID查询1.6.2 数据封装1.6.…

C++引用(变量引用、数组引用与数组指针、引用本质-指针常量、常量引用)

C语言 ——对数组名进行解引用,取地址,还有sizeof和strlen进行操作解析_对数组名解引用得到什么-CSDN博客 C++引用(变量引用、数组引用与数组指针、引用本质-指针常量、常量引用)_c++11 数组引用-CSDN博客

复现文章:R语言复现文章画图

文章目录 介绍数据和代码图1图2图6附图2附图3附图4附图5附图6 介绍 文章提供画图代码和数据&#xff0c;本文记录 数据和代码 数据可从以下链接下载&#xff08;画图所需要的所有数据&#xff09;&#xff1a; 百度云盘链接: https://pan.baidu.com/s/1peU1f8_TG2kUKXftkpYq…

软考系统分析师知识点四:操作系统基本原理

前言 今年报考了11月份的软考高级&#xff1a;系统分析师。 考试时间为&#xff1a;11月9日。 倒计时&#xff1a;33天。 目标&#xff1a;优先应试&#xff0c;其次学习&#xff0c;再次实践。 复习计划第一阶段&#xff1a;扫平基础知识点&#xff0c;仅抽取有用信息&am…

LabVIEW技术难度最大的程序

在LabVIEW开发中&#xff0c;技术难度最大的程序通常涉及复杂的系统架构、高精度的控制要求、大量数据处理&#xff0c;以及跨平台或多硬件设备的集成。以下是几类具有高技术难度的LabVIEW程序&#xff1a; 1. 高精度实时控制系统 LabVIEW中涉及高精度实时控制的系统程序&…

十四、深入理解Mysql索引底层数据结构与算法

文章目录 一、索引的本质1、索引是帮助MySQL高效获取数据的排好序的数据结构2、索引的数据结构3、数据结构可视化网站 二、常见数据结构介绍1、B-Tree2、BTree&#xff08;B-Tree变种&#xff09;3、Hash结构 三、存储引擎的索引实现1、MyISAM存储引擎索引实现MyISAM索引文件和…

Linux搭建Hadoop集群(详细步骤)

前言 Hadoop是一个由Apache基金会所开发的分布式系统基础架构。用户可以在不了解分布式底层细节的情况下&#xff0c;开发分布式程序。充分利用集群的威力进行高速运算和存储。 说白了就是实现一个任务可以在多个电脑上计算的过程。 一&#xff1a;准备工具 1.1 VMware 1.2L…

【中间件学习】Git的命令和企业级开发

一、Git命令 1.1 创建Git本地仓库 仓库是进行版本控制的一个文件目录。我们要想对文件进行版本控制&#xff0c;就必须创建出一个仓库出来。创建一个Git本地仓库对应的命令是 git init &#xff0c;注意命令要在文件目录下执行。 hrxlavm-1lzqn7w2w6:~/gitcode$ pwd /home/hr…

力扣6~10题

题6&#xff08;中等&#xff09;&#xff1a; 思路&#xff1a; 这个相较于前面只能是简单&#xff0c;个人认为&#xff0c;会print打印菱形都能搞这个&#xff0c;直接设置一个2阶数组就好了&#xff0c;只要注意位置变化就好了 python代码&#xff1a; def convert(self,…

复习HTML(进阶)

前言 上一篇的最后我介绍了在表单中&#xff0c;上传文件需要使用到 method属性 和enctype属性。本篇博客主要是详细的介绍这些知识 <form action"http://localhost:8080/test" method"post" enctype"multipart/form-data"> method属性…

clientWidth,offsetWidth,scrollHeight

clientWidth: offsetWidth&#xff1a; scrollHeight&#xff1a;

幂,你去哪儿了-《分析模式》漫谈37

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 “Analysis Patterns”的第3章的图3.5&#xff0c;原文的图是&#xff1a; 2004&#xff08;机械工业出版社&#xff09;中译本的图是&#xff1a; direct翻译成分子&#xff0c;inv…

Python 从入门到实战33(使用MySQL)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了数据库编程接口操作的相关知识。今天我们将学习…

M3u8视频由手机拷贝到电脑之后,通过potplayer播放报错找不到文件地址怎么解决?

该文章前面三节主要介绍M3u8视频是什么&#xff0c;视频播放错误(找不到地址)的解决方法在后面 M3U8是一种多媒体播放列表文件格式&#xff0c;主要用于流媒体播放。 一、文件格式特点 1. 文本文件&#xff1a;M3U8是一个采用 UTF-8 编码的文本文件&#xff0c;这意味着它可…

CSS基础-盒子模型(三)

9、CSS盒子模型 9.1 CSS常用长度单位 1、px&#xff1a;像素&#xff1b; 2、em&#xff1a;相对元素font-size的倍数&#xff1b; 3、rem&#xff1a;相对根字体的大小&#xff0c;html标签即是根&#xff1b; 4、%&#xff1a;相对于父元素进行计算。 注意&#xff1a;CSS样…

基于OpenCV的实时年龄与性别识别(支持CPU和GPU)

关于深度实战社区 我们是一个深度学习领域的独立工作室。团队成员有&#xff1a;中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等&#xff0c;曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万粉丝&#xff0c;拥有2篇国家级人工智能发明专利。 社区特色…

C语言文件操作(上)(27)

文章目录 前言一、为什么要用文件&#xff1f;二、什么是文件&#xff1f;程序文件数据文件文件名文件类型文件缓冲区文件指针 三、流流的概念标准流 总结 前言 C语言可以直接操作文件&#xff0c;如果你是第一次听说这个特性&#xff0c;可能会眼前一亮&#xff0c;感到惊奇  …

四.网络层(上)

目录 4.1网络层功能概述 4.2 SDN基本概念 4.3 路由算法与路由协议 4.3.1什么是路由协议&#xff1f; 4.3.2什么是路由算法&#xff1f; 4.3.3路由算法分类 (1)静态路由算法 (2)动态路由算法 ①全局性 OSPF协议与链路状态算法 ②分散性 RIP协议与距离向量算法 4.3.…