【APUE】标准I/O库
目录
1、简介
2、FILE对象
3、打开和关闭文件
3.1 fopen
3.2 fclose
4、输入输出流
4.1 fgetc
4.2 fputc
4.3 fgets
4.4 fputs
4.5 fread
4.6 fwrite
4.7 printf 族函数
4.8 scanf 族函数
5、文件指针操作
5.1 fseek
5.2 ftell
5.3 rewind
6、缓冲相关
6.1 fflush
6.2 setvbuf
7、补充
7.1 getline
7.2 临时文件
1、简介
I/O : input and output,是一切实现的基础
IO分为标准IO(stdio)和系统调用IO(sysio)
- 系统调用IO根据操作系统的实现方式而定,不同OS有着不同的系统调用IO
- 标准IO对不同OS下的系统调用IO进行了封装,从而提供了一套不同OS下相同IO实现的库函数
2、FILE对象
FILE对象通常是一个结构体,包含了标准I/O库为管理该流需要的所需要的所有信息
FILE类型贯穿始终,可以理解为FILE就代表流
一个进程默认打开了三个流,分别是标准输入 stdin、标准输出 stdout 和标准错误 stderr
一个进程默认打开1024个流,可通过如下命令查看LINUX控制shell程序的资源:
3、打开和关闭文件
3.1 fopen
FILE *fopen(const char *pathname, const char *mode);
// The fopen() function opens the file whose name is the string pointed to by pathname and associates a stream with it.
- pathname — 字符串,表示要打开的文件名称
- mode — 字符串,表示文件的访问模式,该指针指向以下面字符开头的字符串:
mode | 描述(man手册的直接翻译) |
"r" | 为读取而打开文本文件。流定位到文件开头 |
"r+" | 为读写而打开。流定位到文件开头 |
"w" | 将文件截断至0长,或为写入而创建文本文件。流定位到文件开头 |
"w+" | 为读写而打开。文件不存在则创建,否则截断。流定位到文件开头 |
"a" | 为追加(在文件尾写)而打开。文件不存在则创建。流定位到文件末尾 |
"a+" | 为读和追加而打开。文件不存在则创建。读取文件的初始位置是文件的开头,但输出总是追加到文件的结尾 |
只有模式 "r" 和 "r+" 要求文件必须存在,其他模式都可以创建文件;
mode也可以包含字母 b,放在最后或者中间,表示二进制流。例如 "rb"、"r+b";
打开成功返回一个 FILE 指针,否则返回 NULL 并设置全局变量 errno 来标识错误。该全局变量在头文件 errno.h 中声明:(只展示部分)
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
为了通过全局变量 errno 的值得到对应的错误提示信息,可以利用C标准中定义的如下两个函数
#include <stdio.h>
void perror(const char *s);
// 在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用“某些”函数出错时,该函数已经重新设置了errno的值
// perror函数只是将你输入的一些信息和errno所对应的错误一起输出
#include <string.h>
char *strerror(int errnuum);
// 搜索错误号errnum,并返回一个指向错误消息字符串的指针
代码示例:
fopen函数解析:
由函数原型可知,fopen函数返回的是一个FILE类型的指针,FILE是一个结构体,由typedef进行了重命名,而指针实际上是指向结构体的指针。
关键问题:指针指向的哪个区?也就是说FILE结构体放在内存的哪一块?是堆,是栈,还是静态区?
换句话说,在fopen函数内部,FILE对象是如何创建的?
如果创建在栈区,当程序退出这个块时,释放刚才为变量tmp分配的栈内存,因此,会返回一个被释放的内存地址,错误
FILE *fopen(const char *pathname, const char *mode)
{FILE tmp;// 给结构体成员赋值初始化tmp.xxx = xxx;tmp.yyy = yyy;...return &tmp;
}
如果创建在静态区,假如多次调用 fopen 函数,也只能存在一个FILE实例(因为只有这一个内存区供指针指向),最后一次的FILE结构体内容会把前一次的结果覆盖掉,错误
FILE *fopen(const char *pathname, const char *mode)
{static FILE tmp;// 给结构体成员赋值初始化tmp.xxx = xxx;tmp.yyy = yyy;...return &tmp;
}
创建在堆区,这是正确的,此时 tmp 具有动态存储期,从调用 malloc 分配内存到调用 free 释放内存为止,而 free 就在 fclose 函数中被调用
FILE *fopen(const char *pathname, const char *mode)
{FILE * tmp = malloc(sizeof(FILE));// 给结构体成员赋值初始化tmp->xxx = xxx;tmp->yyy = yyy;...return tmp;
}
3.2 fclose
int fclose(FILE *stream);
// The fclose() function flushes the stream pointed to by stream (writing any buffered output data using fflush(3)) and closes the underlying file descriptor.
- stream — 这是指向 FILE 对象的指针,该 FILE 对象指定了要被关闭的流
- 如果流成功关闭,则该方法返回零。如果失败,则返回 EOF
一般来说,fopen 和 fclose 一一对应,fopen 中为 FILE 对象分配动态内存,fclose 中利用 free 释放所分配的动态内存
代码示例:
4、输入输出流
下面仅给出部分字符和字符串的输入输出流操作,详细见 man 手册
- man 3 fgetc
- man 3 fputc
- man 3 fread
- man 3 fwrite
4.1 fgetc
int fgetc(FILE *stream);
// fgetc() reads the next character from stream and returns it as an unsigned char cast to an int,
// or EOF on end of file or error.
功能:从指定流中获取下一个字符
还有几个类似功能的:
int getc(FILE *stream);int getchar(void);
getchar 等同于 getc(stdin);
getc 和 fgetc 使用方式完全相同,fgetc 通过函数实现,而 getc 通过宏定义实现;
fgetc 中的 f 代表的是 function 的意思,而不是 file 的意思;
宏只占用编译时间,不占用调用时间,而函数相反,因此内核的实现通常使用宏来定义函数,因为调用函数的时间通常长于调用宏;
4.2 fputc
int fputc(int c, FILE *stream);
// fputc() writes the character c, cast to an unsigned char, to stream.
功能:将指定字符写入指定流
还有几个类似功能的:
int putc(int c, FILE *stream);int putchar(int c);
putchar 等同于 putc(c, stdout);
putc 和 fputc 使用方式完全相同,fputc 通过函数实现,而 putc 通过宏定义实现;
fputc 中的 f 代表的是 function 的意思,而不是 file 的意思;
宏只占用编译时间,不占用调用时间,而函数相反,因此内核的实现通常使用宏来定义函数,因为调用函数的时间通常长于调用宏;
代码示例:实现一个拷贝文件的功能
将文件 src 拷贝为 dest
./mycpy src dest
实现代码如下:
使用方法:
diff 对两个文件内容进行对比,如果两个文件完全相同,则什么也不输出
4.3 fgets
char *fgets(char *s, int size, FILE *stream);
// fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s.
// Reading stops after an EOF or a newline.
// If a newline is read, it is stored into the buffer.
// A terminating null byte ('\0') is stored after the last character in the buffer.
功能:从指定流中读取批量字符
- s:指向一个 buffer 缓冲,用于储存从指定流中读取到的字符
- size:用于限制每次读取的字符个数最多 size - 1 个
- stream:指定流
fgets 读取结束的条件,满足其一即可:
- 读到 size-1 个字符时停止
- 读到换行符 '\n' 时停止,换行符会被存进缓冲
- 读到文件末尾 EOF
读取结束后,会往读取进 buffer 的最后一个字符后,再添加一个 '\0' ;
如果成功读取到字符,返回 s;
如果发生错误或者什么字符也没读取到,返回 NULL;
任何一个非空文件,末尾都有一个换行符 '\n'
#define SIZE 5
char buf[SIZE]; // 栈上的动态内存
fgets(buf, SIZE, stream);如果stream = "abcde"
则buf = "abcd\0"(读到size-1),文件指针指向e如果stream = "ab"
则buf = "ab\n\0"(读到换行符),文件指针指向EOF极端的情况:
如果stream = "abcd"
则需要fgets读取两次才能读完
第一次读取的为"abcd\0"(读到SIZE-1),指针指向'\n'
第二次读取的为"\n\0"(读到换行符),指针指向EOF
4.4 fputs
int fputs(const char *s, FILE *stream);
// fputs() writes the string s to stream, without its terminating null byte ('\0').
功能:将批量字符(即字符串)写入流
写入流的不包括末尾空字符 '\0'
4.5 fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
// The function fread() reads nmemb items of data,
// each size bytes long,
// from the stream pointed to by stream,
// storing them at the location given by ptr.
- stream — 这是指向 FILE 对象的指针,表示从该文件对象读取;
- nmemb — 待读取元素的个数;
- size — 读取的每个元素的大小,以字节为单位;
- ptr — 将读取到的元素放进 ptr 所指的位置;
函数返回成功读取的元素的数目,如果出错或者达到 EOF,则返回值可能少于 nmemb
示例:
fread(buf, size, nmemb, fp);// 情况1:数据量足够
// 情况2:文件只有5个字节// 读10个对象,每个对象1个字节
fread(buf, 1, 10, fp);// 情况1:
// 第一次读:返回10(读到10个对象),读到10个字节
// 情况2:
// 第一次读:返回5(读到5个对象),读到5个字节//--------------------------------// 读1个对象,每个对象10个字节
fread(buf, 10, 1, fp);// 情况1:
// 第一次读:返回1(读到1个对象),也读到10个字节
// 情况2:
// 第一次读:返回0(读不到1个对象,因为1个对象要10字节,而文件只有5个字节)
因此建议单字节读取
4.6 fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
// The function fwrite() writes nmemb items of data,
// each size bytes long,
// to the stream pointed to by stream,
// obtaining them from the location given by ptr.
- ptr — 从 ptr 所指的内存空间获取待写入元素;
- nmemb — 写入元素的个数;
- size — 写入的每个元素的大小,以字节为单位;
- stream — 这是指向 FILE 对象的指针,表示将元素写入到 stream 输出流;
函数返回成功写入的元素的数目。如果该数字与 nmemb 参数不同,则会显示一个错误。
代码示例:用 fread 和 fwrite 代替 fgtec 和 fputc:
4.7 printf 族函数
#include <stdio.h>int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...); // write at most size bytes (including the terminating null byte ('\0')) to str
- printf:发送格式化输出到标准输出流 stdout;
- fprintf:发送格式化输出到流 stream 中。可以实现格式化输出的重定向;
- sprintf:发送格式化输出到 str 所指内存。它能够将多种数据类型(整型、字符型)的数据综合为字符串类型;
- snprintf:发送格式化输出到 str 所指内存。它能够将多种数据类型(整型、字符型)的数据综合为字符串类型,最多发送 size 个字符(包括末尾的 '\0');
辅助函数:将字符串初始部分转化为整数
#include <stdlib.h>// convert a string to an integerint atoi(const char *nptr); // The atoi() function converts the initial portion of the string pointed to by nptr to int.
long atol(const char *nptr);
long long atoll(const char *nptr);
4.8 scanf 族函数
#include <stdio.h>int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
功能:按照格式说明符读取并解析输入对应位置的信息并存储于可变参数列表中对应的指针所指位置
三者区别:
The scanf() function reads input from the standard input stream stdin, fscanf() reads input from the stream pointer stream, and sscanf() reads its input from the character string pointed to by str.
5、文件指针操作
5.1 fseek
#include <stdio.h>int fseek(FILE *stream, long offset, int whence);// The fseek() function sets the file position indicator for the stream pointed to by stream.
功能:设置文件位置指针指向
- stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了流
- offset — 这是相对 whence 的偏移量,以字节为单位
- whence — 这是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:
常量 | 描述 |
SEEK_SET | 文件的开头 |
SEEK_CUR | 文件位置指针当前所在位置 |
SEEK_END | 文件的末尾EOF,即文件中最后一个字符的下一个位置 |
如果成功,则该函数返回零,否则返回非零值
文件位置指针是什么?
- 文件位置指针用来指示文件中的某个位置,因此在程序中进行读写操作时,位置指针也会随着文件的读写操作而改变
- 在进行读写操作时,位置指针会自动更新到下一个读写的位置。 例如,当进行读操作时,位置指针会自动更新到下一个可读的位置;当进行写操作时,位置指针会自动更新到下一个可写的位置
5.2 ftell
long ftell(FILE *stream);
功能: 返回文件位置指针所指位置(从文件起始位置开始,并以字节为单位度量,相对起始位置的偏移)
5.3 rewind
void rewind(FILE *stream);
功能:设置文件位置指针的位置为给定流 stream 的文件的开头
使用时功能等同于:
(void) fseek(stream, 0L, SEEK_SET)
fseek 和 ftell 函数功能详解:
fseek 和 ftell 中偏移offset的修饰类型是 long,因此只能对2G左右大小的文件进行操作,否则会超出long的范围
fseeko 和 ftello 则将偏移的修饰类型使用typedef定义为offset_t,具体类型交由系统决定,因此不存在文件大小的限制。但是这两个函数不是C标准库函数,而是隶属于POSIX标准(POSIX是标准C库的超集,或者说,C库是普通话,而POSIX是方言)
代码示例:求文件的有效字节数
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>int main(int argc, char **argv){FILE *fp;if(argc < 2) {fprintf(stderr, "Usage...\n");exit(1);}fp = fopen(argv[1], "r");if(fp == NULL) {perror("fopen()");exit(1);}// 将指针定位在文件末尾fseek(fp, 0, SEEK_END);printf("%ld\n", ftell(fp));exit(0);
}
6、缓冲相关
先看一个现象
发现 while 循环前的那行字符串并没有显示!
原因:对于标准输出,输出缓冲区刷新的时机:
- 输出缓冲区满
- 或者遇到换行符\n
- 强制刷新,或者进程结束
因此,上述 while 循环前的那行只是进入输出缓冲区了,并没有冲洗
标准 I/O 提供缓冲的目的是为了减少使用系统调用 read 和 write 的次数,增加程序的吞吐量
6.1 fflush
#include <stdio.h>int fflush(FILE *stream);
功能:冲洗缓冲区
- 如果参数为 stream 为 NULL,则冲洗所有的已打开的流
- 如果成功,该函数返回零值。如果发生错误,则返回 EOF,且设置错误标识符(即 feof)
术语冲洗(flush)说明标准I/O缓冲区的写操作。缓冲区可由标准I/O例程自动地冲洗(例如, 当填满一个缓冲区时),或者可以调用函数 fflush 冲洗一个流。值得注意的是,在UNIX环境中,flush有两种意思。在标准I/O库方面,flush(冲洗)意味着将缓冲区中的内容写到磁盘上(该缓冲区可能只是部分填满的)。在终端驱动程序方面,flush(刷清)表示丢弃已存储在缓冲区中的数据。
可行的一些修改方式:
- 标准输出遇到换行符 '\n' 自动冲洗
- 通过 fflush 手动冲洗 stdout
即可得到期望的输出
标准I/O缓冲的分类(即除了手动 fflush 以外,不同类的缓冲有不同的默认冲洗(标准IO指写入磁盘)时机):
- 全缓冲(块缓冲):在全缓冲的情况下,在填满标准I/O缓冲区后,才进行冲洗
- 行缓冲:行缓冲指的是当遇到换行符时,或者缓冲区已经满了(一般1024字节),执行冲洗
- 无缓冲:不会填缓冲区,可以理解为立即冲洗
不同的标准I/O有默认的缓冲类别
- 磁盘上的文件默认是全缓冲的
- 标准输入和标准输入默认是行缓冲的
- 一般指向终端设备的流默认是行缓冲,而指向文件时,则默认是全缓冲
- 为了立即显示错误信息,标准错误默认是无缓冲的
关于缓冲这段的 man 手册:
6.2 setvbuf
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
// The setvbuf() function may be used on any open stream to change its buffer
功能: 用于改变流的缓冲类别(即改变流在不调用 fflush 的情况下的冲洗时机)
- stream — 这是指向 FILE 对象的指针,该 FILE 对象标识了一个打开的流
- buf — 这是用户指定的用于存缓冲内容的位置。如果设置为 NULL,该函数会自动分配一个指定大小的缓冲空间
- size — the buf argument should point to a buffer at least size bytes long
- mode — 这指定了文件缓冲的类别:
mode | 描述 |
_IOFBF | 全缓冲 |
_IOLBF | 行缓冲 |
_IONBF | 无缓冲 |
7、补充
7.1 getline
之前介绍的函数,都不能获得完整的一整行(有缓冲区大小的限制),而下面介绍的getline函数则可以动态分配内存,当装不下完整一行时,又会申请额外的内存来存储。
getline会生成一个包含一串从输入流读入的字符的字符串,直到以下情况发生会导致生成的此字符串结束:
- 到文件结束
- 遇到函数的定界符
- 输入达到最大限度
#define _GNU_SOURCE // 通常将这种宏写在makefile中,现在的编译器没有了该宏,直接使用即可
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
功能:用于从流中读取完整的行
要理解这些参数的含义,必须要知道 getline 的工作原理
这样再对照 getline 的声明,就知道各种参数和返回值的含义了
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
- lineptr:用于存放开辟空间的首地址,*lineptr 指向所开辟空间
- n:用于存放开辟空间的字节数,*n 为开辟空间的字节数
- 返回值为读取到的字符数,读取失败返回 -1
注意 man 手册中的一句特殊的使用要求:
If *lineptr is set to NULL and *n is set 0 before the call, then getline() will allocate a buffer for storing the line. This buffer should be freed by the user program even if getline() failed.
使用示例:
注意区分开辟空间的字节数和读取到的字符数!
7.2 临时文件
临时文件产生的问题:
- 如何命名不冲突
- 如何保证及时销毁
tmpnam:生成并返回一个有效的临时文件名,该文件名之前是不存在的。如果 str 为空,则只会返回临时文件名。
存在并发问题,可能会产生两个或多个名字相同的临时文件。
可能两个不同进程运行该函数时,检查文件名后,生成文件名前发生了进程切换
#include <stdio.h>
char *tmpnam(char *s);
- s — 这是一个指向字符数组的指针,其中,临时文件名将被存储为 C 字符串
- 返回一个指向 C 字符串的指针,该字符串存储了临时文件名。如果 s 是一个空指针,则该指针指向一个内部缓冲区,缓冲区在下一次调用函数时被覆盖
- 如果 s 不是一个空指针,则返回 s。如果函数未能成功创建可用的文件名,则返回一个空指针
另一个函数:
tmpfile:以二进制更新模式(wb+)创建临时文件。被创建的临时文件会在流关闭的时候或者在程序终止的时候自动删除。
该文件没有名字(匿名文件),函数只返回指向FILE的指针,因此不存在命名冲突的问题,同时会自动删除,因此可以及时销毁。
#include <stdio.h>
FILE *tmpfile(void);
- 如果成功,该函数返回一个指向被创建的临时文件的流指针。如果文件未被创建,则返回 NULL
相关文章:
【APUE】标准I/O库
目录 1、简介 2、FILE对象 3、打开和关闭文件 3.1 fopen 3.2 fclose 4、输入输出流 4.1 fgetc 4.2 fputc 4.3 fgets 4.4 fputs 4.5 fread 4.6 fwrite 4.7 printf 族函数 4.8 scanf 族函数 5、文件指针操作 5.1 fseek 5.2 ftell 5.3 rewind 6、缓冲相关 6.…...
es6---模块化
main.js import { bar } from "./module1"; import module2 from "./module2"; bar() module2()module1.js // 多变量导出,导入变量需要变量名一对一映射 export const module1module1 export function bar(params) {console.log(module1) }m…...
【项目 计网12】4.32UDP通信实现 4.33广播 4.34组播 4.35本地套接字通信
文章目录 4.32UDP通信实现udp_client.cudp_server.c 4.33广播bro_server.cbro_client.c 4.34组播multi_server.cmulti_client.c 4.35本地套接字通信ipc_server.cipc_client.c 4.32UDP通信实现 udp_client.c #include <stdio.h> #include <stdlib.h> #include <…...
创建简单的 Docker 数据科学映像
推荐:使用NSDT场景编辑器快速搭建3D应用场景 为什么选择 Docker for Data Science? 作为一名数据科学家,拥有一个标准化的便携式分析和建模环境至关重要。Docker 提供了一种创建可重用和可共享的数据科学环境的绝佳方法。在本文中ÿ…...
angualr:CSS一个div内两个子元素的高度自适应
问题: 如题 参考: CSS一个div内两个子元素的高度自适应-腾讯云开发者社区-腾讯云...
Java基础之static关键字
目录 静态的特点第一章、静态代码块第二章、静态属性第三章、静态方法调用静态方法时静态方法中调用非静态方法时 第四章、static关键字与其他关键字 友情提醒 先看文章目录,大致了解文章知识点结构,点击文章目录可直接跳转到文章指定位置。 静态的特点…...
iPhone 15 Pro有5项重大设计升级,让iPhone 15看起来很无聊
距离苹果9月份的发布会还有不到一周的时间,我们很快就会第一次看到iPhone 15系列。源源不断的传言表明,这一代人将对大多数机型进行另一次增量更新,这对那些想换iPhone 14或更旧手机的人来说是个坏消息。 但这一次的高端选择,iPh…...
xCode14.3.1运行MonkeyDev出现“Executable Not Found“的解决办法
安装MonkeyDev遇到的坑 环境:Xcode Version 14.3.1 (14E300c) 错误提示 is not a valid path to an executable file. 报错 /Users/xxxx//Library/Developer/Xcode/DerivedData/MonTest-ccparhdyzjuqhjdergwrngpfwwoh/Build/Products/Debug-iphoneos/MonTest.app…...
C# Emgu.CV+Tesseract实现识别图像验证码
效果图,简单的还行,复杂的。。。拉跨 懒得写讲解了,全部源码直接上吧 /// <summary>/// 验证码识别/// </summary>public partial class FrmCodeIdentify : FrmBase{private string _filePath;// 原图像Image<Bgr, byte> …...
ORACLE 11.2.0.4 RAC Cluster not starting cssd with Cannot get GPnP profile
最近,处理一次oracle 11.2.0.4 rac cluster由于cssd无法启动,导致集群一个节点的CRS集群无法正常启动的故障。原本,计划变更是从ASM剔除磁盘,解除存储到数据库服务器的映射;磁盘已经成功从ASM剔除,也已经成…...
Converting Phase Noise to Random Jitter(Cycle-to-Cycle)
借用Phase Noise to Random Jitter(Period)的转换过程推导了Cycle to Cycle random Jitter,一般展频时钟调制,用来评估相邻周期的随机抖动。...
HashMap知识总结
HashMap: 1. 扰动函数hash值右移16位与原hash值做异或运算得出的新hash值散列程度高. 2. 负载因子0.75,就是说一个数组初始化new HashMap(17)容量会比17最小2的n次方大,就是32,想要已空间换时间,就是负载因子小于0.75这样的话hash冲突更低,但是扩容频率更高.3 扩容,jdk…...
PLC编码器测速(限幅滤波+中心差分法求导SCL源代码)
M法测速的基本原理,大家可以查看专栏的系列文章,这里不再赘述常用链接如下: PLC通过编码器反馈值计算速度的推荐做法(算法解析+ST代码)_编码器脉冲怎么转换为速度_RXXW_Dor的博客-CSDN博客PLC如何测量采集编码器的位置数据,不清楚的可以参看我的另一篇博文:三菱FX3U PLC…...
SW的stp文件转成CAD格式文件学习笔记
SW的stp文件转成CAD格式文件 文章目录 SW的stp文件转成CAD格式文件另存为part文件(零件图)另存为CAD文件 另存为part文件(零件图) 如图一个STP文件,右上角标注是什么文件呢 另存为零件图,即另存为part …...
【数据结构】栈---C语言版(详解!!!)
文章目录 🐸一、栈的概念及结构🍄1、栈的概念定义🍄2、动图演示🌲入栈🌲出栈🌲整体过程 🐸二、栈的实现🐸三、数组结构栈详解🍎创建栈的结构⭕接口1:定义结构…...
sqlserver 联表查询、子查询、窗口函数、聚合函数等概念与例子
with cte as的用法 查询的一个有用工具,允许创建临时命名结果集,可在查询中多次引用相同的子查询结果,可以提高查询的可读性和维护性 WITH cte_name (column1, column2, ...) AS (-- 这里是子查询SELECT column1, column2, ...FROM your_ta…...
GO学习之 消息队列(Kafka)
GO系列 1、GO学习之Hello World 2、GO学习之入门语法 3、GO学习之切片操作 4、GO学习之 Map 操作 5、GO学习之 结构体 操作 6、GO学习之 通道(Channel) 7、GO学习之 多线程(goroutine) 8、GO学习之 函数(Function) 9、GO学习之 接口(Interface) 10、GO学习之 网络通信(Net/Htt…...
搭建自己的OCR服务,第三步:PPOCRLabel标注工具安装
一、安装说明 安装好了PaddleOCR后,还需要安装PPOCRLabel这个标注工具,想要自己训练模型的话,有个标注工具会起很大作用。 尤其是PPOCRLabel就是跟PaddleOCR配套的标注工具,同样是开源的。 在下载 PaddleOCR 整个源码中&#x…...
Java学习笔记37——网络编程01
网络编程入门 网络编程入门网络编程概述网路编程的三要素ip地址InetAddress类的使用端口 网络编程入门 网络编程概述 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理…...
powershell 搜索文本并返回行号
目录 powershell 搜索文本并返回行号 python调用powershell搜索文本并返回行号; powershell 搜索文本并返回行号 $keyword PS dir "d:\" -Filter "*.txt" -Recurse | foreach {$line 0 $fileName $_.FullNameGet-Content $fileName | f…...
网络原理
网络原理 传输层 UDP 特点 特点:无连接,不可靠,面向数据报,全双工 格式 怎么进行校验呢? 把UDP数据报中的源端口,目的端口,UDP报文长度的每个字节,都依次进行累加 把累加结果&a…...
力扣(LeetCode)算法_C++——同构字符串
给定两个字符串 s 和 t ,判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相…...
网管实战⑼:配置华为S5720交换机
配置好汇聚交换机后,需要根据单位情况配置具体的接入交换机。 自从2019年12月底配置好交换机后,基本上都没有怎么操作交换机了。那时候使用的是H3C交换机,主要是H3C S7706、H3C S5120、H3C S5130、H3C S5500、H3C S3600等型号的交换机&#x…...
文件上传漏洞第十六关十七关
第十六关 第十七关 第十六关 直接上传php文件判断限制方式: 同第十五关白名单限制 第十六关源码: 代码逻辑判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染 二次渲染图片马&…...
Try llama2 in NUC (by quqi99)
作者:张华 发表于:2023-09-06 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 ) 据说现在在PC机上可以运行llama2大模型了, Way 1 于是照…...
强大易用的开源 建站工具Halo
特点 可插拔架构 Halo 采用可插拔架构,功能模块之间耦合度低、灵活性提高。支持用户按需安装、卸载插件,操作便捷。同时提供插件开发接口以确保较高扩展性和可维护性。 ☑ 支持在运行时安装和卸载插件 ☑ 更加方便地集成三方平台 ☑ 统一的可配置设置表…...
如何使用vuex
1.安装vuex 2.在store文件夹内写index.js 此处tab是自定义的文件 import Vue from "vue" import Vuex from "vuex" import tab from "./tab"Vue.use(Vuex)export default new Vuex.Store({modules:{tab} }) 3.在store文件夹内写tab.js(自定义…...
动手深度学习——Windows下的环境安装流程(一步一步安装,图文并配)
目录 环境安装官网步骤图文版安装Miniconda下载包含本书全部代码的压缩包使用conda创建虚拟(运行)环境使用conda创建虚拟环境并安装本书需要的软件激活之前创建的环境打开Jupyter记事本 环境安装 文章参考来源:http://t.csdn.cn/tu8V8 官网…...
个人博客系统-测试用例+自动化测试
一、个人博客系统测试用例 二、自动化测试 使用selenium4 Junit5单元测试框架,来进行简单的自动化测试。 1. 准备工作 (1)引入依赖,此时的pom.xml文件: <?xml version"1.0" encoding"UTF-8&quo…...
C语言文件读写常用函数
文章目录 1. fopen函数2. fclose函数3. fgetc函数4. fgets函数5. fputc函数6. fputs函数7. fprintf函数8. fscanf函数9. fseek函数10. ftell函数 1. fopen函数 返回值:文件指针(FILE*)参数:文件名(包括文件路径&#…...
哪里有做装修网站/小红书关键词热度查询
使用Numpy内部功能函数 Numpy具有用于创建数组的内置函数。 创建一个一维的数组 arrange是一种广泛使用的函数,用于快速创建数组。 >>> import numpy as np >>> arraynp.arange(20) >>> array array([ 0, 1, 2, 3, 4, 5, 6, …...
做酒店管理网站的作用/软文500字范文
前面几个小节,我们分别介绍了冒泡排序,插入排序,直接快速排序 ,选择排序本节,我们介绍插入排序的改进版的希尔排序。 希尔排序是1959年,Shell发明的,这是第一个突破O(n2)的排序算法,…...
免费网站打包app/网站建设网络营销
Simple Tabs OneTwoThree 新增的tab会闪烁 $(#container).tabs(); 新增的Tab可关闭 新增的tab点击后不再闪烁 样式有干扰,还是下载自己打开看吧:download 新增了闪烁同步和不同步两种实现:download...
flash html网站模板/关键词采集软件
path表示需要查找的路径,string表示需要包含的字符\字符串 grep -rnw path -e "string"只查找包含特定string的所有.c和.h文件 grep --include\*.{c,h} -rnw -rnw path -e "string" 除去所有.o文件,查找其他文件是否包含特定strin…...
做catia数据的网站/百度学术论文查重官网
一、canvas介绍 <canvas> 标签用于绘制图像(通过脚本,通常是 JavaScript),<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器) - 必须使用脚本来完成实际的绘图任务。 不支持canvas的浏览器:ie8及以下 绘制环境:getcontext…...
wordpress mobile 主题/苏州关键词优化软件
(1) 进入目录手动删除 configure作用:是源码安装软件时配置环境用的 他根据你的配置选项和你的系统情况生成makefile文件 为make 做准备 最常用的参数: ./configure --prefix 作用:不指定prefix,则可执行文件默认放在/usr/local/bin,库文件默认放在/usr/…...