一篇就看懂的文件操作

news2024/12/23 9:46:32

文件操作1


为什么使用文件

我们前面学习结构体时,写了通讯录的程序,当通讯录运行起来的时候,可以给通讯录中增加、删除数据,此时数据是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了,等下次运行通讯录程序的时候,数据又得重新录入,如果使用这样的通讯录就很难受。我们在想既然是通讯录就应该把信息记录下来,只有我们自己选择删除数据的时候,数据才不复存在。这就涉及到了数据持久化的问题,我们一般数据持久化的方法有,把数据存放在磁盘文件、存放到数据库等方式。

使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

文件的概念

磁盘上的文件是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件数据文件(从文件功能的角度来分类的)。

程序文件

包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。

数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。在以前各章所处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。

其实有时候我们会把信息输出到磁盘,当有需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上文件。

文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。文件名包含3部分:文件路径+文件名主干+文件后缀例如:c:\code\test.txt为了方便起见,文件标识常被称为文件名

文件的打开和关闭

文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE。例如,VS2013编译环境提供的stdio.h头文件中有以下的文件类型申明:

struct_iobuf{
    char*_ptr;
    int   _cnt;
    char*_base;
    int   _flag;
    int   _file;
    int   _charbuf;
    int   _bufsiz;
    char*_tmpfname;
};
typedefstruct_iodufFILE;

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。一般都是通过一个FILE的指针来维这个FILE地指针来维护这个FILE结构的变量,这样使用起来更加方便。下面我们可以创建一个FILE*的指针变量:

FILE*pf;//文件指针变量

定义pf是一个指向FILE类型的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件

文件的打开和关闭fopen/fclose

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。ANSIC规定使用fopen函数来打开文件,fclose来关闭文件。

//打开文件

FILE*fopen( constchar*filename, constchar*mode );

//关闭文件

intfclose( FILE*stream );
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
intmain()
{
    FILE*pf=fopen("test.dat", "w");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //写文件
    
    //关闭文件
    fclose( pf );
    pf=NULL;
    return0;
}

文件使用方式

文件使用方式

含义

如果指定文件不存在

"r"(只读)

为了输入数据,打开一个已存在的文本文件

出错

"w"(只读)

为了输出数据,打开一个文本文件

建立一个新的文件

"a"(追加)

想文本文件尾添加数据

建立一个新的文件

"rb"(只读)

为了输入数据,打开一个二进制文件

出错

"wb"(只写)

为了输入数据,打开一个二进制文件

建立一个新的文件

"ab"(追加)

向一个二进制文件尾添加数据

出错

"r+"(读写)

为了读和写,打开一个文本文件

出错

"w+"(读写)

为了读和写,建议一个文本文件

建立一个新的文件

"a+"(读写)

打开一个文件,在文件尾进行读写

建立一个新的文件

"rb+"(读写)

为了读和写打开一个二进制文件

出错

"wb+"(读写)

为了读和写,新建一个新的二进制文件

建立一个新的文件

"ab+"(读写)

打开一个二进制文件,在文件尾进行读和写

建立一个新的文件

实例代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
    FILE*pf=fopen("test.dat", "w");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //写文件
    
    //关闭文件
    fclose( pf );
    pf=NULL;
    return0;
}

文件的顺序读写

功能

函数名

适用于

字符输入函数

fgetc

所有输入流

字符输出函数

fputc

所有输出流

文本行输入函数

fgets

所有输入流

文本行输出函数

fputs

所有输出流

格式化输入函数

fscanf

所有输入流

格式化输出函数

fprintf

所有输出流

二进制输入

fread

文件

二进制输出

rwrite

文件

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
intmain()
{
    FILE*pf=fopen("test.dat", "w");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //写文件
    fputc('b',pf);
    fputc('i',pf);
    fputc('t',pf);
    //关闭文件
    fclose( pf );
    pf=NULL;
    return0;
}
#include<stdio.h>
intmain()
{
    FILE*pf=fopen("test.dat", "r");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读取文件
    intch=fgetc(pf);
    printf("%c\n",ch);//b
    ch=fgetc(pf);
    printf("%c\n",ch);//i
    ch=fgetc(pf);
    printf("%c\n",ch);//t
    //关闭文件
    fclose( pf );
    pf=NULL;
    return0;
}

对比一组函数

scanf / fscanf / sscanf

printf / fprintf / sprintf

函数

scanf()

针对标准输入的格式化的输入语句-stdin

fscanf()

针对所有输入流的格式化的输入语句-stdin/文件

sscanf()

读取格式化的字符串中的数据

printf()

针对标准输出的格式化的输出语句-stdin

fprintf()

针对所有输出流的格式化的输出语句-stdout/文件

sprintf()

字符串格式化命令

intsprintf(char*buffer, constchar*format[,argument]……);

格式化的数据,转化成字符串

#include<stdio.h>
structS
{
    chararr[10];
    intage;
    floatf;
};
​
intmain()
{
    structSs= { "hello", 20, 5.5f };
    charbuf[100] = { 0 };
    //sprintf把一个格式化的数据,转化成字符串
    sprintf( buf, "%s %d %f",s.arr,s.age,s.f );
    printf("%s\n",buf);
    return0;
}
字符串还原为格式化的数据
#include<stdio.h>
structS
{
    chararr[10];
    intage;
    floatf;
};
​
intmain()
{
    structSs= { "hello", 20, 5.5f };
    structStmp= { 0 };
    charbuf[100] = { 0 };
    //sprintf把一个格式化的数据,转化成字符串
    sprintf( buf, "%s %d %f",s.arr,s.age,s.f );
    printf("%s\n",buf);
    //从buf字符串还原成一个结构体数据
    sscanf(buf,"%s %d %f",tmp.arr,&(tmp.age),&(tmp.f));
    printf("%s %d %f",tmp.arr,tmp.age,tmp.f);
    return0;
}

流是一个高度抽象的概念。

因为程序要表现和存储在屏幕上、硬盘上、U盘上、光盘上、网络上、软盘上,这就会很复杂,程序员的负担也会由此增加,于是就在程序和上述外部设备间抽象出来一个流,然后通过流的传递到各个指定的部分去。

在C语言程序中,只要运行起来,就默认打开了3个流:stdin、stdout、stderr。都是由FILE*指向的。

stdin —— 标准数据流——键盘

stdout——标准输出流——屏幕

stderr——标准输出流——屏幕

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
intmain()
{
    fputc('b',stdout);
    fputc('i',stdout);
    fputc('t',stdout);
    return0;
}
bit

文本行输入输出

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
intmain()
{
    intret=fgetc(stdin);//返回的是ASCLL码值
    printf("%c\n",ret);
    intret=fgetc(stdin);//返回的是ASCLL码值
    printf("%c\n",ret);
    intret=fgetc(stdin);//返回的是ASCLL码值
    printf("%c\n",ret);
    return0;
}

fputs

以文本形式写入文件

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
intmain()
{
    FILE*pf=fopen("test.dat","w");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //写文件-按照行来写
    fputs("abcdef\n",pf);
    fputws("qwertyuiop\n",pf);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return0;
}

fgets

读文件

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
intmain()
{
    chararr[10] = { 0 };
    FILE*pf=fopen("test.dat","r");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读文件
    fgets(arr,4,pf);
    printf("%s\n",arr);
    fgets(arr,4,pf);
    printf("%s\n",arr);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return0;
}

abc

def//没有读四个,要留一个\0的位置

格式化输入输出

输入和输出所讲的格式化可以类比。

我们在进行输入的时候,其实都是一个字符串,但是这个字符串被输入后有可能当成整数来用,也有可能还是字符串,这个计算机自己是不知道规则的,需要写代码的人告诉它,这个告诉它如何输入的过程就被称为格式化。

我们在进行输出的时候,对于小数而言,可能需要输出小数点后一位,亦或是两位,这个计算机自己是不知道规则的,需要写代码的人告诉它,这个告诉它如何输出的过程就被称为格式化。

fprintf

写入文件

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
structS
{
    chararr[10];
    intnum;
    floatsc;
};
​
intmain()
{
    structSs= { "abcdef",10,5.5f };
    //对格式化的数据进行写文件
    FILE*pf=fopen("text.test","w");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //写文件
    fprintf(pf, "%s %d %f", s.arr,s.num,s.sc);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return0;
}

intprintf( constchar*format[,argument]……);//可变参数

intfprintf(FILE*stream, constchar*format[,argument]……);

intscanf( constchar*format[,argument]……);//可变参数

intfscanf(FILE*stream, constchar*format[,argument]……);

fscanf

读入文件

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
structS
{
    chararr[10];
    intnum;
    floatsc;
};
​
intmain()
{
    structSs= { 0 };
    //对格式化的数据进行写文件
    FILE*pf=fopen("text.test","w");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读文件
    fscanf(pf, "%s %d %f", s.arr,&(s.num),&(s.sc));
    printf("%s %d %f", s.arr,s.num,s.sc);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return0;
}

二进制的读写

fwrite

size_tfwrite( constvoid*buffer, size_tsize, size_tcount, FILE*stream );
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
structS
{
    chararr[10];
    intnum;
    floatsc;
};
​
intmain()
{
    structSs= { "abcdef", 10, 5.5f };
    //对格式化的数据进行写文件
    FILE*pf=fopen("text.test","w");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读文件
    fwrite(&s, sizeof(structS), 1,pf );
    //关闭文件
    fclose(pf);
    pf=NULL;
    return0;
}
利用fwrite进行读取文件:上述代码在文本中的信息是abcdef+后面一串乱码。

fread

size_tfread( constvoid*buffer, size_tsize, size_tcount, FILE*stream );

fwrite是将指针buffer指向size大小的内容至stream中,而fread恰恰相反,是将stream里的内容指向buffer中。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
structS
{
    chararr[10];
    intnum;
    floatsc;
};
​
intmain()
{
    structSs= { 0 };
    //二进制的形式读取
    FILE*pf=fopen("text.test","r");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读文件
    fread(&s, sizeof(structS), 1, pf );
    
    printf("%s %d %f\n",s.arr,s.num,s.sc);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return0;
}

输出结果:abcdef105.500000

文件的随机读写

fseek

根据文件指针的位置和偏移量来定位文件指针。

intfseek( FILE*stream, longintoffset, intorigin );

例子:

/* fseek example */
#include<stdio.h>
intmain()
{
    FILE*pFile;
    pFile=fopen( "example.txt", "wb" );
    fputs( "This is an apple.", pFile );
    fseek( pFile, 9, SEEK_SET );
    fputs( " sam", pFile );
    fclose( pFile );
    return0;
}

调整文件指针

#include<stdio.h>
intmain()
{
    FILE*pf=fopen("test.dat", "r");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读取文件
    intch=fgetc(pf);
    printf("%c\n",ch);//b
    
    //调整文件指针
    fseek(pf, -1, SEEK_CUR);//SEEK_END
    ch=fgetc(pf);
    printf("%c\n",ch);//b
    ch=fgetc(pf);
    printf("%c\n",ch);//i
    
    //关闭文件
    fclose( pf );
    pf=NULL;
    return0;
}

ftell

返回文件指针相对于起始位置的偏移量

longintftell( FILE*stream );

例子

#include<stdio.h>
intmain()
{
    FILE*pf=fopen("test.dat", "r");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读取文件
    intch=fgetc(pf);
    printf("%c\n",ch);//b
    
    //调整文件指针
    fseek(pf, -1, SEEK_CUR);//SEEK_END
    ch=fgetc(pf);
    printf("%c\n",ch);//b
    ch=fgetc(pf);
    printf("%c\n",ch);//i
    
    intret=ftell(pf);
    printf("%d\n",ret);//3
    //关闭文件
    fclose( pf );
    pf=NULL;
    return0;
}

rewind

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

voidrewind( FILE*stream );

#include<stdio.h>
intmain()
{
    FILE*pf=fopen("test.dat", "r");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //读取文件
    intch=fgetc(pf);
    printf("%c\n",ch);//b
    
    //调整文件指针
    fseek(pf, -1, SEEK_CUR);//SEEK_END
    ch=fgetc(pf);
    printf("%c\n",ch);//b
    ch=fgetc(pf);
    printf("%c\n",ch);//i
    
    intret=ftell(pf);
    printf("%d\n",ret);//2
    
    //让文件指针回到起始位置
    rewind(pf);
    ch=fgetc(pf);
    printf("%c\n",ch);//b
    //关闭文件
    fclose( pf );
    pf=NULL;
    return0;
}

文本文件和二进制文件

根据数据的组织形式,数据文件被称为文本文件或者二进制文件。数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。如果要求在外存上以ASCLL码的形式存储,则需要在存储前转换。以ASCLL字符的形式存储的文件就是文本文件。一个数据在内存中是怎么存储的呢?字符一律以ASCLL形式存储,数值型数据既可以用ASCLL形式存储,也可以使用二进制形式存储。如有整数10000,如果以ASCLL码的形式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制形式输出。则在磁盘上只占4个字节(VS2013测试)。

内存中10000(十进制)的存储形式

二进制文件:00000000 00000000 00100111 00010000

ASCLL码形式,文本文件:00110001 00110000 00110000 00110000 00110000

#include<stdio.h>
intmain()
{
    inta=10000;
    FILE*pf=fopen("test.txt","wb");
    if(pf==NULL)
    {
        perror("fopen");
        return1;
    }
    //写文件
    fwrite(&a, sizeof(int), 1, pf);//二进制的形式写入文件
    fclose(pf);
    pf=NULL;
    return0;
}

文件读取结束的判定

被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用判断文件的是否结束。而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束

  1. 文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets)例如:fgetc判断是否为EOF。fgetc函数在读取结束的时候会返回EOF,正常读取的时候返回的是读取到的字符的ASCLL码值。fgets判断返回值是否为NULL。fgets函数在读取结束的时候会返回NULL,正常读取的时候返回存放字符串的空间起始地址。

  1. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。例如:fread判断返回值是否小于实际要读的个数。fread函数在读取的时候,返回的是实际读取到的完整元素的个数,如果发现读取到的完整的元素个数小于指定的元素个数,这就是最后一次读取了。

正确的使用:

写代码把test.txt文件拷贝一份,生成test2.txt

#include<stdio.h>
intmain()
{
    FILE*pfread=fopen("test.txt","r");
    if(pfread==NULL)
    {
        return1;
    }
    FILE*pfwrite=fopen("test2.txt","w");
    if(pfwrite==NULL)
    {
        fclose(pfread);
        pfread=NULL;
        return1;
    }
    //文件打开成功
    //读写文件
    intch=0;
    while((ch=fgetc(pfread) !=EOF))
    {
        //写文件
        fputc(ch, pfwrite);
    }
    //关闭文件
    fclose(pfread);
    pfread=NULL;
    fclose(pfwrite);
    pfwrite=NULL;
    return0;
}

文本文件的例子

#include<stdio.h>
intmain()
{
    intc;//注意:int,非int,要求处理EOF
    FILE*fp=fopen("test.txt","r");
    if(!fp)
    {
        perror("File opening failed");
        returnEXIT_FAILURE;
    }
    //fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while((c=fgetc(fp)) !=EOF)
    {
        putchar(c);
    }
    //判断是什么原因结束的
    if(ferror(fp))
    {
        puts("I/O error when reading");
    }
    elseif(feof(fp))
    {
        puts("EOF of file reached successfully");
    }
    
    fclose(fp);
}

二进制文件的例子

#include<stdio.h>
enum
{
    SIZE=5
};
​
intmain(void)
{
    doublea[SIZE] = { 1.,2.,3.,4.,5. };
    FILE*fp=fopen("test.bin","wb");//必须使用二进制模式
    fwrite(a, sizeof*a, SIZE, fp);//写double的数组
    fclose(fp);
    
    doubleb[SIZE];
    fp=fopen("test.bin","rb");
    size_tret_code=fread(b, sizeof*b, SIZE, fp);//读double的数组
    if(ret_code==SIZE)
    {
        puts("Array read successfully, contents:");
        for(intn=0;n<SIZE; ++n)
        {
            printf("%f ",b[n]);
        }
        putchar('\n');
    }
    else
    {
        //error handing
        if(feof(fp))
            printf("Error reading test.bin: unexpected end of file\n");
        elseif(ferror(fp))
            perror("Error reading test.bin");
    }
    fclose(fp);
    return0;
}

文件缓冲区

ANSIC标准采用”缓冲文件系统"处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

如下代码可以测试:

#include<stdio.h>
#include<windows.h>
//vs2013 WIN10环境调试
intmain()
{
    FILE*pf=fopen("test.txt","w");
    fputs("abcdef", pf);//先将代码放在输出缓冲区
    printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
    Sleep(10000);
    printf("刷新缓冲区\n");
    fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
    //注:fflush在高版本的VS上不能使用了
    printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
    Sleep(10000);
    fclose(pf);
    //注:fcolse在关闭文件的时候,也会刷新缓冲区
    pf=NULL;
    return0;
}

这里可以得出一个结论:因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。

希望大家能给个赞,鼓励一下,谢谢!!!!蟹蟹!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java并发编程】 interrupt 方法详解

【Java并发编程】 interrupt 方法详解 文章目录【Java并发编程】 interrupt 方法详解1.介绍2.打断阻塞状态线程3.打断正常状态的线程4.两阶段终止模式5.打断 park 线程1.介绍 程序中&#xff0c;有些线程的终端需要外部干预&#xff0c;比如有线程存在while(true)循环&#xf…

值得拥有并收藏的 3个安卓/鸿蒙手机解锁软件

手机无论支持哪种操作系统&#xff0c;都占据了每个人口袋里的空间。随着大量移动设备的使用&#xff0c;搜索引擎上也出现了同样数量的查询&#xff0c;其中最常见的是提供安卓/鸿蒙屏幕锁定删除工具。由于安卓是当今最畅销的设备&#xff0c;我们的首要任务是为您提供最好的安…

矿山安全生产监测预警系统 opencv

矿山安全生产监测预警系统通过pythonopencv网络模型计算机视觉技术&#xff0c;对现场画面中人的不安全行为”、“物的不安全状态”、“环境的不安全因素”三方面出发进行实时监测&#xff0c;当监测到现场画面中人员未穿反光衣行为、明火烟雾、未穿安全帽行为、矿车掉道识别、…

【王道数据结构】第三章 | 栈和队列

目录 一、栈stack 基本概念 基本操作 存储结构​​​​​​​ 二、队列Queue 基本概念 队列的基本操作 存储结构 三、栈的应用 栈在括号匹配中的应用 栈在表达式求值中的应用​编辑 栈在递归中的应用 一、栈stack 基本概念 只允许在一端(栈顶top)进行插入或删除操…

大数据看全国疫情生活,北京、武汉已过疫情拐点

自2022年11月末&#xff0c;很多地区新冠病例数据呈现下降趋势&#xff0c;与实际感知有明显差异。2022年12月14日&#xff0c;国家疾控中心发布消息&#xff0c;核酸检测实行“愿检尽检”&#xff0c;不再公布无症状感染者数据。因此&#xff0c;网友们想要了解所在地和老家的…

python能做的100件事04 - python解析PDF

1. python常用pdf库 名称特点PyPDF2已不再维护&#xff0c;继任者PyPDF4 ,但很长时间没有更新了,能读不能写pdfrw能读不能写&#xff0c;但可以兼容ReportLab写ReportLab商业版的开源版本&#xff0c;能写不能读pikepdf能读不能写pdfplumber能读不能写PyMuPDF读写均可,基于GPL…

Vue面试题2

1&#xff1a;vue.js的两个核心是什么&#xff1f; 答:数据驱动和组件化。 2&#xff1a;vue生命周期钩子函数有哪些&#xff1f; 答:总共分为8个阶段创建前/后&#xff0c;载入前/后&#xff0c;更新前/后&#xff0c;销毁前/后 3&#xff1a;第一次页面加载会触发哪几个钩子…

C语言二维数组中:主次对角线求和,上下三角求和,杨辉三角,矩阵转置

p8 有些的结论需要直接记住 目录 矩阵转置 主对角线和次对角线 下三角 和上三角&#xff08;一般是让求和&#xff09; 下三角 上三角 杨辉三角 矩阵转置 不是方阵 需要用到第二个二维数组 b[i][j]a[i][j] 是方阵 方法1 借助第二个二维数组&#xff0c;同上 方…

C++基础-3函数

一、函数 1.概述 作用&#xff1a;将一段经常使用的代码封装起来&#xff0c;减少重复代码 而一个较大的程序&#xff0c;一般分为若干个代码块&#xff0c;每个模块实现特定的功能 2.定义 5个内容&#xff1a; ①返回值类型 ②函数名 ③参数列表 ④函…

力扣刷题记录——1287. 有序数组中出现次数超过25%的元素、1299. 将每个元素替换为右侧最大元素 、1413. 逐步求和得到正数的最小值

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《力扣刷题记录——1287. 有序数组中出现次数超过25%的元素…

【vector的模拟实现】

目录 1 类的成员变量 2 常用成员函数和迭代器 3 增删查改 3.1 reverse 3.2 push_back 3.3 resize 3.4 insert && erase 4 默认成员函数 4.1 构造函数 4.2 拷贝构造 4.3 赋值运算符重载 4.4 析构函数 前面我们详细介绍了string类的使用&#xff0c;vector的…

关于 JSON 数据格式的完全使用指南

前言 本文将对 JSON 的语法、解析、序列化进行详细的说明&#xff0c;帮助大家掌握 JSON 的使用方式。 如果文中有不对、疑惑或者错字的地方&#xff0c;欢迎在评论区留言指正&#x1f33b; 一、JSON简介 在 JSON 之前&#xff0c;XML 曾经一度成为互联网上传输数据的事实标…

【论文阅读】【剪枝】Learning Efficient Convolutional Networks through Network Slimming

摘要 深度卷积神经网络&#xff08;CNN&#xff09;在许多实际应用中的部署在很大程度上受到其高计算成本的阻碍。在本文中&#xff0c;我们提出了一种新的神经网络学习方案&#xff0c;以同时1&#xff09;减小模型大小&#xff1b;2&#xff09; 减少运行时内存占用&…

Kali Linux- 社会工程及压力工具教程

在本章中&#xff0c;我们将了解 Kali Linux 中使用的社会工程工具。 文章目录社会工程Kali Linux - 压力工具SlowhttptestinvitefloodTHC-SSL-DOS总结社会工程 社会工程师工具包 &#xff08;SET&#xff09; 是一个专为社会工程设计的开源渗透测试框架。SET具有许多自定义攻…

第九章(12):STL之常用查找算法

文章目录前情回顾常用查找算法findfind_ifadjacent_findbinary_searchcountcount_if下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&#xff0c;在学习C/C的路上会越走越远&#xff0c;后面不定期更新有关C/C语法&#xff0…

读懂用户之用户调研怎么做?(内附模板教程)

随着互联网的发展&#xff0c;不管是做产品设计、运营&#xff0c;还是市场推广&#xff0c;我们都需要思考的是“用户真正想要的是什么&#xff1f;”。这时候&#xff0c;用户调研的重要性就凸显出来了。 一、什么是用户调研 用户调研&#xff0c;指通过各种方式得到受访者的…

Redis常用指令

3. 常用指令 在这部分中呢&#xff0c;我们家学习两个知识&#xff0c;第一个是key的常用指令&#xff0c;第二个是数据库的常用指令。和前面我们学数据类型做一下区分&#xff0c;前面你学的那些指令呢&#xff0c;都是针对某一个数据类型操作的&#xff0c;现在学的都是对所…

#14环形链表#

环形链表 1题目链接 链接 2思路 slow和fast指向链表的开始 slow一次走一步 fast一次走两步 不带环 fast就会为空 带环 fast就会在环里追上slow 3实现 bool hasCycle(struct ListNode* head) {struct ListNode* slow head, * fast head;while (fast && fast->ne…

微信小程序学习第3天——网络数据请求

一、小程序网络请求限制 1、必须https类型的接口 2、必须将接口的域名添加到信任列表中 二、配置request合法域名 配置步骤&#xff1a;登录微信小程序管理后台 -> 开发 -> 开发设置 -> 服务器域名 -> 修改 request 合法域名 点击修改request合法域名&#xf…

【自动化测试】从0开始玩转docker—— 01软件安装

目的 CI / CD在目前各类互联网企业中已然成为推动软件开发行为的重要基础设施服务。同样的对于测试团队来说更是有着举足轻重的重大意义&#xff0c;无论是测试左移的具象化提现亦或是持续测试的顺利开展&#xff0c;掌握这一技能已是广大软件测试工程师的必修课。分享这一技术…