初识C语言·文件操作
目录
1 关于文件
i)文件的基本知识
ii)数据文件的分类
2 文件打开和关闭
i)流和标准流
ii)文件指针
iii)文件打开和关闭
3 文件的顺序读写
i) fgetc fputc
ii) fgets fputs
iii) fscanf fprintf
iv) fwrite fread
4 对比一组函数 scanf/fscanf/sscanf/printf/fprintf/sprintf
5 文件的随机读写
6 文件读取结束的判定
7 文件缓冲区
1 关于文件
i)文件的基本知识
在电脑中文件是随处可见的,那你思考过为什么存在“文件”吗?当我们运行程序的时候,程序一旦结束,在内存中存储的数据也会被销毁,我们如果想要保存数据,以方便下一次使用的话,就需要用到文件,也就是说,文件是可以用来保存数据的。
那什么是文件呢?从文件的功能性分类的话,文件可以分为程序性文件和数据文件,程序性文件包括源文件(.c后缀),目标文件(windows后缀为.obj),可执行程序(windows后缀为.exe),我们本章着重介绍的是数据文件,程序文件会在后面的预编译章节介绍。在之前的章节我们处理数据的输入输出都是在终端处理的,如键盘,电脑屏幕,但有点时候我们会把信息输入到磁盘里面,读取数据的时候让磁盘输入数据给内存,在从内存中读取数据,计算机读取数据分为好几个等级,从速度快慢分为寄存器,缓存,内存,硬盘等等,那么本场要学习的就是如何从磁盘从读取数据。
要使用文件,我们肯定要知道文件标识是由什么组成的,⽂件名包含3部分:⽂件路径+⽂件名主⼲+⽂件后缀,例如c:\code\test.txt,就是一个完整的文件名,文件路径是c:\code\,文件名主干是test,文件后缀就是txt,为了方便起见,我们一般把文件标识称作为文件名。
ii)数据文件的分类
数据文件被分为二进制文件和文本文件,有的文件创建好了之后不是给使用者看的,是给计算机看的,但是计算机只能识别二进制的1 0,所以会有二进制文件,那么同理可得,文本文件就是给使用者看的,如果当你使用了记事本打开一个文件发现全是乱码,那么它八九不离十的是二进制文件了。
二进制文件是数据在内存中不加转化,直接输出到外存的文件,数据文件需要经过ASCII码值的转化,再输出到外存,所以以ASCII码值存储的文件都是文本文件。
那么一个数据是怎么在内存中存储的呢?
字符一律以ASCII码值的形式存储,数值类型的数据可以用二进制的形式存储也可以用ASCII码值的形式存储,以10000来举个例子,10000的二进制是这样的,(VS2019测试)如果直接以二进制的形式存储,就只会占4个字节,如果是ASCII码值的形式存储,那么就会占5个字节,1占一个字节,其余的每个0占一个字节
00000000 00000000 00100111 00010000
当我们使用二进制存储的时候,10000的二进制存储就会变为00 00 27 10,那么因为VS是小端存储,所以屏幕上看到的就是10 27 00 00
int main()
{int a = 10000;FILE* pf = fopen("data.txt", "wb");fwrite(&a, 4, 1, pf);fclose(pf);pf = NULL;return 0;
}
使用fwrite函数创建该文件,并且以二进制的形式存入,最后我们使用二进制的方式打开该文件,得到的就是:
2 文件打开和关闭
i)流和标准流
计算机输出数据和输入数据的时候需要外接到同设备,而通过不同的外接设备输入输出的数据的时候操作都不一样,那么计算机为了简化这一过程,就引用了流的概念,可以理解为计算机将数据不管三七二十一的一股脑给丢进去一个地方,计算机需要数据的时候就去里面拿就行了,那个地方就是流,C语言一般画面,文件,键盘的输入输出的时候都是通过流完成的,那么我们要使用流或者是输入数据到流里面,就需要打开流,使用完再关闭流。
可是实际上我们之前写代码的时候并没有过打开流关闭流这个操作,这是因为C语言默认打开了三个流,这三个流被称为标准流,stdin,stdout,stderr
stdin被称为标准输入流,大多数情况从键盘输入,scanf使用的时候就需要使用到这个流。
stdout被称为标准输出流,大多数情况从屏幕输出,printf使用的时候就需要使用到这个流。
stderr被称为标准错误流,大多数情况写也是从屏幕输出的。
当然,流也是由类型的,这三个流的类型是FILE*,FILE的英文意思就是文件,也就是文件指针,C语言中,FILE*的使用也是用来维护各种流的使用的。
ii)文件指针
文件类型指针就是FILE*,简称文件指针,而每个使用的文件在内存中都开辟了一块文件信息区,文件的相关信息,而这些信息保存在一个结构体变量里面,这个结构体变量就是FILE*,在vs2013关于FILE*的声明是这样的:
struct _iobuf {char *_ptr;int _cnt;char *_base;int _flag;int _file;int _charbuf;int _bufsiz;char *_tmpfname;};
typedef struct _iobuf FILE;
创建了一个结构体变量_iobuf,最后重命名为了FILE,而在VS2022声明就没有那么详细了,VS2022的的声明如下:
当然我们只需要关心怎么用FILE*就行,至于文件指针的源码,是不用了解那么多的,我们使用FILE*访问文件信息区的时候就可以找到文件的相关信息,也就是说我们可以利用文件指针间接找到与该文件相关的文件。
iii)文件打开和关闭
文件打开的时候会返回一个指针指向该文件的文件信息区,也就是建立了指针和文件的关系,那么我们使用完之后就应该关闭文件,C语言中打开文件使用的是fopen函数,关闭文件使用的是fclose函数,f就是file,open就是打开的意思,close就是关闭的意思。
//打开⽂件
FILE * fopen ( const char * filename, const char * mode );
//关闭⽂件
int fclose ( FILE * stream );
这是他们的参数,fopen的第一个参数就是文件名,第二个是打开模式,fclose参数就是文件指针,也就是用来接受fopen函数返回的文件指针。
文件的打开模式有许多种,如下:
模式有很多种,感兴趣可以自行使用一下。注意如果文件不存在的话,就会创建一个这样的文件放在该代码的路径下,这是相对路径,如果想要指定路径放的话,就是绝对路径:
FILE* pf = fopen("C:\\Users\\users\\OneDrive\\data.txt", "w");
只需要在文件名前面加上文件路径就行了,但是要注意的是\要写两个,这是前面转义字符的知识,为了防止\和其他字符结合形成转义字符。
但是多次是用"w"打开文件的时候,每次打开都会先让文件里面的内容清空,这个小现象需要注意一下。
3 文件的顺序读写
i) fgetc fputc
fgetc是字符输入函数,fputc是字符输出函数,均适用于所有文件输入输出流。
int main()
{FILE* pf = fopen("data.txt", "w");assert(pf);char array[26] = { 0 };for (int i = 0; i < 26; i++){fputc('a' + i, pf);}for (int j = 0; j < 26; j++){array[j] = fgetc(pf);}for (int j = 0; j < 26; j++){printf("%c ", array[j]);}fclose(pf);pf = NULL;return 0;
}
我们创建好文件指针之后,需要判断一下指针是不是空指,最后还要关闭指针,并且置为空指针,这里和动态开辟函数类似,我们给文件里面存好数据之后,第一遍是打印不出来我们想要的26个字符的,因为这里的文件打开模式是w,是写入,那么运行第二次时,我们把w换成r就fgetc函数就开始操作了。
如果fgetc函数读取失败返回或者是读取到了文件尾就会返回eof,也就是文件结束标志,那么函数就结束了,如果fputc写入失败的话也是返回的eof。
在读取文件的时候,字符函数都是一个字符一个字符的读取或者写入的,当读取完一个字符后,光标往后移动,指向下一个字符,所以如果不用for循环的话,想要打印就需要重复写这两行代码:
int ch = fgetc(pf);printf("%c ", ch);
实际上fgetc函数等效于getc函数,只是getc函数在库中可以等效为宏。
ii) fgets fputs
fgets是文本行输入函数,fputs是文本行输出函数,均适用于所有输入输出流,文本行其实就是字符串。
fgets和gets函数是非常不像的,fgets函数有三个参数:
char * fgets ( char * str, int num, FILE * stream );
fgets函数会从流里面读取num -1个字符,并将这些字符存到指针str里面,且最后一个元素置为\0,读取过程中如果碰到了换行符 文件末尾 或者是读取了num - 1个字符,以先到者为准,读取num - 1个字符,第num个字符是\0,如果读取失败,返回的是空指针,如果读着读着莫名读取到了文件尾,那么返回的就是eof。
fputs就没有什么好介绍的了,就是将字符串放进去而已,puts输出之后会自动换行,fputs不会,这是他们的区别。
参考代码:
int main(){FILE* pf = fopen("data.txt", "r");assert(pf);char arr[10] = { 1,2,3,4,5,6,7,8,9,10 };fputs("xxxxxxx", pf);fgets(arr, 6, pf);for (int i = 0; i < 6; i++){printf("%c ", arr[i]);}return 0;
}
iii) fscanf fprintf
fscanf fprintf这两个函数是格式化输入输出函数,也就是要用到占位符,适用于所有流,可以这么说scanf能做的,fscanf都可以做,fprintf同理,fscanf就比scanf多了一个参数,fscanf是从文件中读取数据,如果第一个参数是stdin,也就是标准输入流的话,就是从键盘里面输入数据了,fprintf同理可得,如果第一个参数是stdout,也就是标准输出流的话,就是从屏幕上打印,这是函数原型:
int fscanf ( FILE * stream, const char * format, ... );
int fprintf ( FILE * stream, const char * format, ... );
int main()
{FILE* pf = fopen("data.txt", "r");assert(pf);char ch = 0;//fputs("1 2 3 4 5 6 7 8 9 10", pf);fscanf(pf, "%c",&ch);printf("%c", ch);fclose(pf);pf = NULL;return 0;
}
这就是从文件里面读取数据,如果我们想要从键盘读取,只需把流换成stdin就行了,那么这是读文件的操作,如果是写文件,就可以用到fprintf:
int main()
{struct St {int age;char name[20];double score;};FILE* pf = fopen("data.txt", "r");assert(pf);struct St st = { 10,"zhangsan",99.9};fscanf(pf, "%d %s %lf", &(st.age), st.name, &(st.score));fprintf(stdout, "%d %s %.1f", st.age, st.name, st.score);fclose(pf);pf = NULL;return 0;
}
iv) fwrite fread
fwrite fread是二进制输入输出函数,只适用于文件
这是cplusplus里面的记述,fwrite有四个参数,意思就是从流里面写进去count个大小为size的元素,用到的是指针,文章最开始就用了这个函数,存的是10000,因为只用存一个10000,所以第三个参数是1,fread同理可得。
因为是二进制输入输出函数,所以写入的时候用到的是wb,读取的时候用到的是rb:
int main()
{FILE* pf = fopen("data.txt", "wb");struct St{int age;//10char name[20];//zhangsandouble score;//99.9}st = {10,"zhangsan",99.9};fwrite(&st,sizeof(st),1,pf);fclose(pf);pf = NULL;return 0;
}
这是我们用二进制的方式写进了文件里面:
文本文件写进去是这样的:
可以看到有明显的差别,因为字符都是以ASCII码值的形式存储,所以结果不变,但是其他数据就变化大了,当然我们是看不懂的,计算机看得懂,比如用fread函数就看懂了:
int main()
{FILE* pf = fopen("data.txt", "rb");struct St{int age;//10char name[20];//zhangsandouble score;//99.9}st;fread(&st, sizeof(st), 1, pf);printf("%d %s %lf", st.age, st.name, st.score);fclose(pf);pf = NULL;return 0;
}
4 对比一组函数 scanf/fscanf/sscanf/printf/fprintf/sprintf
scanf printf都是标准流的格式化函数,fscanf fprintf是所有流的格式化函数,scanf printf能做的
fscanf fprintf都可以做,可以理解为fscanf fprintf包含了scanf printf,前面介绍了这两组函数,这里就不介绍了
sscanf sprintf:
sprintf的作用是将格式化的数据放到指针指向的空间里面,sscanf的作用是从指针指向的空间种读取格式化的数据(代码如下):
int main()
{struct XY{char name[10];int age;float score;}xy = {"ziyou",18,100.8};char arr[100] = { 0 };sprintf(arr, "%s %d %f", xy.name, xy.age, xy.score);printf("%s", arr);return 0;
}
创建好一个结构体变量之后,再创建一个字符数组用来存放sprintf输出的数据,那么格式化的占位符是必不可少的,因为数组名是首元素地址,也就是指针,所以写上了arr,最后打印出来如下:
因为我在fprintf写参数的时候已经空格了,空格也会输出进去,所以打出来也是带空格的。
int main()
{struct XY{char name[10];int age;float score;}xy = { "zhangsan",12,12.2 }, tem = { 0 };char arr1[100] = { 0 };sprintf(arr1, "%s %d %f", xy.name, xy.age, xy.score);sscanf(arr1, "%s %d %f", tem.name, &(tem.age), &(tem.score));printf("%s %d %f", tem.name,tem.age,tem.score);return 0;
}
sscanf是从arr1里面读取数据,然后放在了结构体里面,sprintf是输出到arr1里面,相较于前面的两组函数,这组函数是没有用到文件指针的,但是指针是用到了,由此可见指针的重要性。
5 文件的随机读写
文件的随机读写介绍三个函数 fseek ftell rewind:
int main()
{FILE* pf = fopen("data.txt", "r");assert(pf);for (int i = 0; i < 26; i++){fputc('a' + i, pf);}char ch = fgetc(pf);printf("%c ", ch);//ach = fgetc(pf);printf("%c ", ch);//bch = fgetc(pf);printf("%c ", ch);//cch = fgetc(pf);printf("%c ", ch);//dch = fgetc(pf);printf("%c ", ch);//efclose(pf);pf = NULL;return 0;
}
这段代码的意思就是文件里面有英文字母26个,使用fgetc函数一个一个读取,最后的打印结果应该是a b c d e,运行到d的时候文件指针,也就是光标,指向的是e,那么如果我们想要让文件指针回到最开始的位置,使得最后的打印结果还是a,就可以用到rewind:
int main()
{FILE* pf = fopen("data.txt", "r");assert(pf);for (int i = 0; i < 26; i++){fputc('a' + i, pf);}char ch = fgetc(pf);printf("%c ", ch);//ach = fgetc(pf);printf("%c ", ch);//bch = fgetc(pf);printf("%c ", ch);//cch = fgetc(pf);printf("%c ", ch);//drewind(pf);ch = fgetc(pf);printf("%c ", ch);//efclose(pf);pf = NULL;return 0;
}
rewind的参数就是一个文件指针,所以想要让文件指针回到起始位置用到一个rewind就行了。
那么如果我们想指定位置开始读取呢?这里用到的函数就是fseek函数,随机读取函数,可以
使文件指针指向最开始到结尾的任意位置:
它有3个参数,第一个参数是文件指针,第二个是偏移量,第三个是计算偏移量的起始位置,偏移量很好理解,光标指向第一个字符的时候偏移量就是0,往后一次偏移量增加1,那么第三个参数写的时候有三个选择,SEEK_SET,SEEK_CUR,SEEK_END,CUR就是当前位置的意思,SET就是起始位置的意思,END就是末尾的意思,所以移动光标的时候需要先确定好计算偏移量的起始位置,然后确定偏移量,从起始位置开始,往左计算偏移量就是负数,往右计算就是正数。
那么如果我懒我不想计算偏移量,我想直接知道现在的偏移量呢?只需要用ftell函数就是,参数就是文件指针,这个函数的返回值就是当前的偏移量。
如下:
int main()
{FILE* pf = fopen("data.txt", "r");assert(pf);for (int i = 0; i < 26; i++){fputc('a' + i, pf);}char ch = fgetc(pf);printf("%c ", ch);//ach = fgetc(pf);printf("%c ", ch);//bch = fgetc(pf);printf("%c ", ch);//cch = fgetc(pf);printf("%c ", ch);//dint num = ftell(pf);printf("%d ", num);//rewind(pf);fseek(pf, -2, SEEK_CUR);ch = fgetc(pf);printf("%c ", ch);//cfclose(pf);pf = NULL;return 0;
}
6 文件读取结束的判定
文件读取结束分为正常读取到了结尾和读到一半遇到错误了,那么我们如何判断文件是不是正常结束呢?这里用到的函数是feof,但是使用feof的前提是文件已经读取完了(不管是哪种结束),需要注意的是feof不能用来判断文件是不是读取结束了,这是前提,不要搞混淆了。
得feof 的作⽤是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到⽂件尾结束。
同理得ferror的作用是:当⽂件读取结束的时候,判断是读取结束的原因是否是:遇到错误结束。
当读取文本文件的时候,fgetc如果正常读取结束返回的是eof,fgets如果正常读取结束返回的是NULL,这也是它们的区别。
当读取二进制文件的时候,判断fread返回的值是否小于文件中的实际字符数,因为fread函数的返回值是读取到的个数。
文本文件代码示范:
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);
}
二进制代码示范:
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);pf = NULL;
}
7 文件缓冲区
前面提到程序从计算机中读取数据的时候分为了好几个层次,其中包括看文件缓冲区,那么缓冲区的作用是是什么呢?
程序运行的时候内存会为每个正在使用的文件开辟缓冲区,读取数据的时候,数据就会往先往里面放,直到缓冲区装满了,才会一并送到磁盘中,相同的,如果程序需要输入数据,系统会将输入的数据放到输入缓冲区里面区,直到输入缓冲区满了,才会从磁盘输入到程序里面去。
那么缓冲区存在的意义是什么呢?
有人会说为什么不输出一个就给磁盘一个,实际上调用函数的时候,计算机底层也会被调用起来,所以看似工作的有程序,内存等,实际上还有计算机各个部分都是调用起来的,如果输出一个就传送一个出去,那其他部分的工作就是进行不下去,所以缓冲区存在的意义就是为了提高工作效率。
int main()
{FILE*pf = fopen("test.txt", "w");fputs("abcdef", pf);//先将代码放在输出缓冲区printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");Sleep(10000);printf("刷新缓冲区\n");fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)了printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");Sleep(10000);fclose(pf);//注:fclose在关闭⽂件的时候,也会刷新缓冲区pf = NULL;return 0;
}
我们先給文件一串字符串,然后让程序休眠10秒,也就是Sleep,Sleep需要引用到的头文件是windows,程序休眠的这10秒,我们打开文件就会发现abcdef是没有被写进去的,这个时候我们使用fflush刷新一下缓冲区,再去打开文件,就会发现abcdef写进去了,这个时候关闭文件,需要注意的是关闭文件的时候缓冲区也会被刷新,验证的方法就是把fclose提前,不使用fflush,这个时候也会发现文件过了10秒之后abcdef出现在了文件里面。
正因为缓冲区的存在,在进行关于文件类操作的时候,需要刷新缓冲区或者是关闭文件,不然很可能导致读写文件出现问题。
感谢阅读!
相关文章:

初识C语言·文件操作
目录 1 关于文件 i)文件的基本知识 ii)数据文件的分类 2 文件打开和关闭 i)流和标准流 ii)文件指针 iii)文件打开和关闭 3 文件的顺序读写 i) fgetc fputc ii) fgets fputs iii) fscanf fprintf iv) fwrite fread 4 对比一组函数 scanf/fscanf/sscanf/printf/fpri…...

跨境卖家:如何利用自养号测评抢占市场先机?
在当今的跨境电商领域,产品的销量和评价是影响产品在市场上的表现的关键因素。对于卖家而言,自行养号进行产品测评不仅有助于提升销量,更成为了他们在这个竞争激烈的市场中保持竞争力的必备策略。 相较于一些卖家仍然依赖于服务商进行测评&a…...

开发手札:Github Timeout 22
今天(2024.01.26日),提交github又出现了ssh connect timeout errorcode 22,不论是创建新的sshkey还是配置.ssh/config都没用。 偶然在知乎上看到了解决方案,只需要在host中添加: 140.82.113.4 githu…...

学习鸿蒙基础(3)
1.组件重用样式 如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,可以采用公共样式进行复用的装饰器Styles。 Styles装饰器可以将多条样式设置…...

2024/1/27 备战蓝桥杯 1-2
目录 金币 0金币 - 蓝桥云课 (lanqiao.cn) 天干地支 0天干地支 - 蓝桥云课 (lanqiao.cn) 明明的随机数 0明明的随机数 - 蓝桥云课 (lanqiao.cn) 浇灌 0灌溉 - 蓝桥云课 (lanqiao.cn) 金币 0金币 - 蓝桥云课 (lanqiao.cn) 思路:放两种情况(k:代…...

【PyQt】02-基本UI
文章目录 前言一、首先了解什么是GUI?二、初学程序1.界面展示代码运行结果 2.控件2.1按钮展示代码运行结果 2.2 纯文本和输入框代码运行结果 3、重新设置大小 -resize4、移动窗口-move()5、设置界面在电脑中央5.1 代码运行结果 6、设置窗口图标代码运行结果 7、布局…...

无需 Root 卸载手机预装软件,精简过的老年机又行了
基础准备 准备目标手机、USB 数据线、以及一台电脑。手机 USB 连接电脑,开发者选项中打开 USB 调试。(开发者选项默认隐藏,需要在关于手机中多次点击版本号才能调出)。 安装手机驱动,下载安装 ADB 工具包。 开始操作…...

【Spring连载】使用Spring Data访问Redis(一)----快速指南
【Spring连载】使用Spring Data访问Redis(一)----快速指南 一、导入依赖二、Hello World程序 一、导入依赖 在pom.xml文件加入如下依赖就可以下载到spring data redis的jar包了: <dependency><groupId>org.springframework.boot…...

Redis 学习笔记 2:Java 客户端
Redis 学习笔记 2:Java 客户端 常见的 Redis Java 客户端有三种: Jedis,优点是API 风格与 Redis 命令命名保持一致,容易上手,缺点是连接实例是线程不安全的,多线程场景需要用线程池来管理连接。Redisson&…...

React Native
学习目标 解决以下问题: 1.什么是 React Native ?为什么它的名字中有 “Native” 字样? 2.为什么 React Native 如此之酷? 3.我们可以分别使用 React Native 和 React 来开发什么? 4.为什么会出现 ReactDOM ?它是做什…...

分布式搜索引擎_学习笔记_3
分布式搜索引擎03 0.学习目标 1.数据聚合 **聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售…...

机器学习系列——(二)主要任务
导语: 随着信息时代的到来,机器学习作为一项重要技术正逐渐渗透到我们的生活和工作中。它的主要任务是通过使用数据和算法,让计算机系统从中学习并改进性能,使其能够更智能地处理问题和做出决策。本文将详细介绍机器学习的主要任…...

十分钟快速上手Spring Boot与微信小程序API接口的调用,快速开发小程序后端服务
1.1 微信小程序API接口介绍 微信小程序API接口是连接小程序前端与后端服务器的桥梁,它提供了丰富的功能接口,包括用户信息、支付、模板消息、数据存储等。这些API接口能够满足开发者在小程序中实现各种复杂业务逻辑的需求。 用户信息接口 用户信息接口…...

理想架构的高回退Doherty功率放大器理论与ADS仿真-Multistage
理想架构的高回退Doherty功率放大器理论与仿真-Multistage 参考: 三路Doherty设计 01 射频基础知识–基础概念 Switchmode RF and Microwave Power Amplifiers、 理想架构的Doherty功率放大器(等分经典款)的理论与ADS电流源仿真参考&#x…...

<网络安全>《11 网络安全审计系统》
1 概念 审计是对资料作出证据搜集及分析,以评估企业状况,然后就资料及一般公认准则之间的相关程度作出结论及报告。 国际互联网络安全审计(网络备案),是为了加强和规范互联网安全技术防范工作,保障互联网…...

飞桨paddlespeech语音唤醒推理C INT8 定点实现
前面的文章(飞桨paddlespeech语音唤醒推理C定点实现)讲了INT16的定点实现。因为目前商用的语音唤醒方案推理几乎都是INT8的定点实现,于是我又做了INT8的定点实现。 实现前做了一番调研。量化主要包括权重值量化和激活值量化。权重值由于较小且…...

go 面试题分享
1 判断字符串中字符是否全都不同 问题描述 请实现一个算法,确定一个字符串的所有字符【是否全都不同】。这里我们要 求【不允许使用额外的存储结构】。给定一个string,请返回一个bool 值,true代表所有字符全都不同,false代表存在相同的字…...

华为VRP系统简介
因为现在国内主流是华为、华三、锐捷的设备趋势,然后考的证书也是相关的,对于华为设备的一个了解也是需要的。 一、VRP概述 华为的VRP(通用路由平台)是华为公司数据通信产品的通用操作系统平台,作为华为公司从低端到核心的全系列路由器、以太…...

SpringMVC实现对网页的访问,在请求控制器中创建处理请求的方法
目录 测试HelloWorld RequestMapping注解 RequestMapping注解的位置 RequestMapping注解的value属性 RequestMapping注解的method属性 SpringMVC支持路径中的占位符(重点) SpringMVC获取请求参数 1、通过ServletAPI获取 2、通过控制器方法的形参…...

c++循环解释
在C中,循环是一种重复执行特定代码块的结构。它允许程序多次执行相同的代码,直到满足特定条件为止。 C中有三种主要类型的循环结构: while循环:在开始执行循环前,判断条件是否为真。如果条件为真,则执行循…...

Hadoop3.x基础(2)- HDFS
来源:B站尚硅谷 目录 HDFS概述HDFS产出背景及定义HDFS优缺点HDFS组成架构HDFS文件块大小(面试重点) HDFS的Shell操作(开发重点)基本语法命令大全常用命令实操准备工作上传下载HDFS直接操作 HDFS的API操作HDFS的API案例…...

04 避免 Latch 的产生
Latch 是什么 latch 即锁存器,是一种对电平敏感的存储单元电路,和寄存器一样都是基本存储单元,但是寄存器是边沿触发的存储器,锁存器是电平触发的存储器。 组合逻辑电路和时序逻辑电路 在数字电路中将逻辑电路分成两大类&#…...

嵌入式学习第十四天!(结构体、共用体、枚举、位运算)
1. 结构体: 1. 结构体类型定义: 嵌入式学习第十三天!(const指针、函数指针和指针函数、构造数据类型)-CSDN博客 2. 结构体变量的定义: 嵌入式学习第十三天!(const指针、函数指针和…...

Unix/Linux上的五种IO模型
a.阻塞 blocking 调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的去检查这个函数有没有返回,必须等这个函数返回才能进行下一步动作。 注意:阻塞并不是函数的行为,而是跟文件描述符有关。通…...

电脑风扇控制温度软件 Macs Fan Control Pro 中文
Macs Fan Control Pro是一款专为Mac用户设计的风扇控制软件,旨在提供更精细的风扇转速控制和温度监控。这款软件通过实时监测Mac内部硬件的温度,自动或手动调整风扇的转速,以确保系统温度保持在理想范围内。 Macs Fan Control Pro提供了直观…...

初谈C++:引用
文章目录 前言概述引用特性应用场景做参数做返回值 传值、传引用效率比较引用和指针的区别 前言 在学习C语言的时候会遇到指针,会有一级指针、二级指针…很容易让人头昏脑胀。在C里面,引入了引用的概念,会减少对指针的使用。引用相当于给一个…...

C++ 数论相关题目 博弈论:拆分-Nim游戏
给定 n 堆石子,两位玩家轮流操作,每次操作可以取走其中的一堆石子,然后放入两堆规模更小的石子(新堆规模可以为 0 ,且两个新堆的石子总数可以大于取走的那堆石子数),最后无法进行操作的人视为失…...

EDR、SIEM、SOAR 和 XDR 的区别
在一个名为网络安全谷的神秘小镇,居住着四位守护者,他们分别是EDR(艾迪)、SIEM(西姆)、SOAR(索亚)和XDR(艾克斯)。他们各自拥有独特的能力,共同守…...

修复idea,eclipse ,clion控制台中文乱码
控制台乱码问题主要原因并不在编译器IDE身上,还主要是Windows的控制台默认编码问题。。。 Powershell,cmd等默认编码可能不是UTF-8,无需改动IDE的settings或者properties(这治标不治本),直接让Windows系统…...

怎样使用Oxygen XML Editor将MS Word转换成DITA
▲ 搜索“大龙谈智能内容”关注公众号▲ 前阵子分享过一篇文章:《如何将Word/PDF转成高质量XML》。 文章中分享了将Word/PDF转换成高质量XML的思路和大体步骤。有朋友问:有什么工具可以做这个数据转换,具体怎么操作呢? 今天就来…...