首页 > 其他分享 >操作文件

操作文件

时间:2023-01-08 18:56:42浏览次数:33  
标签:fp 文件 txt fp1 fp2 操作 fopen

操作文件

认识文件

什么是文件

通常计算机包含各种不同类型的文件,例如照片、音乐、.c文件等

文件包含程序文件数据文件

将数据的输入和输出的过程称为数据流

一个文件名包含文件路径、文件标识符、文件后缀

例如:D:\vscode\coin\hello world.exe

后缀名exe(可执行文件)、txt(文本文件)、doc(word文件)、mp4(视频文件)、mp3(音频文件)等

文件的分类

数据文件分为ASCII文件和二进制文件

数据在内存中是以二进制的形式存储的

文件缓冲区

从磁盘中读取数据,会先将数据存储到输入文件缓冲区中,

等文件缓冲区装满了之后发送到程序数据区

输出文件到磁盘中,会现将数据存储到输出文件缓冲区中,

等文件缓冲区装满了之后在发送给磁盘

graph RL 磁盘 --> 输入文件缓冲区 输入文件缓冲区 --> 程序数据区 程序数据区 --> 输出文件缓冲区 输出文件缓冲区 --> 磁盘

文件的操作

对文件的操作方法

graph LR 打开文件 ---> 读取文件内容 --->关闭文件 打开文件 ---> 写入文件内容 --->关闭文件 打开文件 ---> 删除文件内容 --->关闭文件 打开文件 ---> 修改文件内容 --->关闭文件

打开文件

打开文件不同于我们操作系统打开文件

打开文件的方法为:

fopen(文件名, 操作模式)

例如:

fopen("D://vscode//coin//hello world.txt","r");		//当打开的文件与代码文件在同一目录下时,则可以省去路径;路径"\",替换为"/" "//" "\\"
//fopen("hello world.txt","r");

fopen为打开函数,文件名为需要打开的文件,操作模式为需要对文件进行何种操作

一旦文件被打开,在内存中开辟区域存放文件的有关信息(如文件的名字、文件的位置、文件的状态等)并返回此信息

定义一个FILE类型的指针变量指向被打开文件,可以将文件信息和指针变量进行关联。之后都可以对文件型指针变量进行操作

打开文件的常用方法为:

FILE *fp 
fp =  fopen(文件名, 操作模式)

打开模式

  • “r”读模式;允许对文件读取信息。若文件名不正确,则报错

    示例:

    #include "stdio.h"
    void main()
    {
        int i;
        FILE *fp;
        fp = fopen("hello world.txt", "r");
        for (i = 0; i < 20; i++)
            printf("%c", fgetc(fp));    // printf("%d",fp->);
        i = fclose(fp);
        printf("%d", i);
    }
    

    结果:

    hello world                   0
    
    Press any key to continue
    
  • “w”写模式;允许向文件写入信息。若文件不存在,则创建一个文件

    示例:

    #include "stdio.h"
    void main()
    {
        int i;
        char x = 'Q';
        FILE *fp;
        fp = fopen("time.txt", "w");
        for (i = 0; i < 20; i++)
            fputc(x, fp);
        i = fclose(fp);
        printf("%d", i);
    }
    

    结果:

    0
    
    Press any key to continue
    

    代码运行后在目录下双击文件打开后会显示文件内容(这里运行后文件内容为20个'Q');如果将char x = 'Q';修改为char x = 'W';并运行,那么文件内容则为20个'W',即使目录下有相同的文件,文件内容也会为20个'W',相当于代码每运行一次,就会重新创建一次文件(如果目录下已有相同的文件,则会进行替换)

  • “a”追加模式;允许在文件末尾添加信息。若文件名不正确,则报错

    示例:

    #include "stdio.h"
    void main()
    {
      int i;
      char x = 'E';
      FILE *fp;
      fp = fopen("time.txt", "a");
      for (i = 0; i < 20; i++)
          fputc(x, fp);
      i = fclose(fp);
      printf("%d", i);
    }
    

    结果:

    0
    
    Press any key to continue
    

    代码运行后在目录下双击文件打开后会显示文件内容(如果文件有内容的话,则会在末尾添加20个'E')

  • “rb” “wb” “ab”打开二进制文件,其他与以上3个相同

  • “r+” “w+” ”a+”允许对文件读取和写入信息,其他与前3个相同

    示例:

    #include "stdio.h"
    void main()
    {
      int i;
      char x = 'Q';
      FILE *fp;
      fp = fopen("hello world.txt", "r+");
      for (i = 0; i < 20; i++)
          printf("%c", fgetc(fp));
      for (i = 0; i < 20; i++)
          fputc(x, fp);
      i = fclose(fp);
      printf("%d", i);
    }
    

    结果:

    hello world                   0
    
    Press any key to continue
    

    代码运行后在目录下双击文件打开后会显示文件内容(如果文件有内容的话,则会在末尾添加20个'Q')

  • “rb+” “wb+” “ab+”允许对文件读取和写入信息,打开二进制文件,其他与前3个相同

:文件名和操作模式都要使用双引号

关闭文件

文件使用后需要关闭文件,如果没有及时关闭文件可能会导致数据的丢失。关闭成功返回一个数值0,否则返回EOF(-1)

fclose(文件指针)

文件的读写

文件打开之后,根据文件的打开模式,可以进行读写

向文件读取字符

fgetc( fp )

功能:从fp指向的文件获取一个字符。如果读取成功返回获取的字符,读取失败则返回文件结束标志EOF(-1)

示例:

#include "stdio.h"
void main()
{
    FILE *fp;
    fp = fopen("hello world.txt", "r");
    char a;
    a = fgetc(fp);
    while (a != EOF)
    {
        printf("%c", a);
        a = fgetc(fp);
    }
    fclose(fp);
}

结果:

hello world
hello world
hello world

Press any key to continue

向文件写入字符

fputc( c , fp )

功能:向fp指向的文件写入一个字符。如果写入成功返回写入的字符,写入失败则返回文件结束标志EOF(-1)

实例:将hello world.txt文件的内容复制到copy.txt文件中

示例:

#include "stdio.h"
void main()
{
    char a;
    FILE *fp1, *fp2;
    fp1 = fopen("hello world.txt", "r");	//权限的设定可以减少误操作
    fp2 = fopen("copy.txt", "w");
    while (a != EOF)
    {
        a = fgetc(fp1);
        fputc(a, fp2);
    }
    fclose(fp1);
    fclose(fp2);
}

结果:

Press any key to continue

代码运行后会在目录下创建复制的文件,双击文件打开后会显示文件内容,文件内容会与被复制的文件内容一样

向文件读取字符串

fgets( str, n , fp )

功能:从fp指向的文件获取一个长度为n-1的字符串,并一次性存入到str字符数组中。如果读取成功返回str指针,读取失败则返回NULL

示例:

#include "stdio.h"
void main()
{
    char str[50];
    FILE *fp;
    fp = fopen("test.txt", "r");
    fgets(str, 10, fp); // fgets(str,50,fp);
    printf("%s", str);
    fclose(fp);
}

结果:

test

Press any key to continue

注:

  • 读取的n-1个字符,最后加上一个结束标志\0,一共n个字符串
  • 遇到换行符或文件结束标志EOF,则将之前的内容存储到str中,不在继续读取字符,表示本次读取结束(最多读取一行)

向文件写入字符串

fputs( str, fp )

功能:将str字符数组中的内容(字符串)写入到fp指向的文件中。如果写入成功返回数字0,写入失败则返回非0的数字

示例:

#include "stdio.h"
void main()
{
    char x[100];
    FILE *fp;
    fp = fopen("experiment.txt", "w");
    fputs("hello world\n", fp);
    gets(x);
    fputs(x, fp);
    fclose(fp);
}

结果:

test		// "test"由手动输入

Press any key to continue

代码运行后会在目录下创建文件,双击文件打开后会显示文件内容,文件内容为"hello world \n test"

格式化读写内容

输出

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

示例:

#include "stdio.h"
void main()
{
	int a = 123;
	float b = 3.1415f;
	FILE *fp;
	fp = fopen("test.txt","w");
	fprintf(fp,"%d %5.3f",a,b);
	fclose(fp);
}

结果:

Press any key to continue

代码运行后会在目录下创建文件,双击文件打开后会显示文件内容,文件内容为"123 3.141"

输入

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

示例:

#include "stdio.h"
void main()
{
	int a;
	float b;
	FILE *fp;
	fp = fopen("test.txt","r");
	fscanf(fp,"%d %f",&a,&b);
	printf("%d %f",a,b);
	fclose(fp);
}

结果:

123 3.141000

Press any key to continue

与printf、scanf函数相同,不同点在于不是输出到黑框的终端或在终端输入信息,而是向文件写入信息或读取信息

向文件读取一个数据块

fread(buffer, size, count, fp )
/*
参数:
buffer: 读取的数据存入内存地址
size: 读取的字节大小
count: 读取数据的个数
fp: 读取的文件指针
返回值: 返回读取数据的个数
*/

读取数据时,数据不经过转换的读取到内存中

示例:

#include "stdio.h"
#include "stdlib.h"
void main()
{
	char *s;
	s = malloc(100);
	FILE *fp;
	fp = fopen("testing.txt","r");
	fread(s,sizeof(char),100,fp);	// sizeof(char) 可以替换为  1
	s[100]='\0';
	printf("%s",s);
	fclose(fp);
}

结果:

testing
testing
testing
testing

Press any key to continue

向文件写入一个数据块

fwrite(buffer, size, count, fp )
/*
参数:
buffer: 待写入的内存地址buffer
size: 写入的字节大小
count: 写入数据的个数
fp: 写入的文件指针
*/

写入数据时,数据不经过转换的读取到内存中

示例:

#include "stdio.h"
#include "stdlib.h"
void main()
{
	char *a = "hello world";
	FILE *fp;
	fp = fopen("tests.txt","w");
	fwrite(a,sizeof(char),15,fp);
	fclose(fp);
}

结果:

Press any key to continue

代码运行后会在目录下创建文件,双击文件打开后会显示文件内容,文件内容为"hello world"

  • 由于fread、fwrite函数读写数据时不会转换数据,因此读取速度快
  • 读取二进制文件一般使用fread、fwrite函数
  • fgetc、fputc、fgets、fputs、fprintf、fscanf函数是读写字符数据,不建议用读取二进制文件

实例

读写结构体

示例:

#include "stdio.h"
struct test 
{
	char name[20];
	int age ;
}stu = {"lisi",21};
void main()
{
	FILE *fp;
	fp = fopen("stu.txt","w");
	fwrite(&stu,sizeof(struct test),1,fp);
	fclose(fp);
}

结果:

Press any key to continue

代码运行后会在目录下创建文件,双击文件打开后会显示文件内容,文件内容为"lisi ......(省略号表示其它内容,也可能是乱码)"


复制二进制文件出错!

示例:

#include "stdio.h"
void main()
{
	char a;
	FILE *fp1, *fp2;
	fp1 = fopen("test.exe","r");
	fp2 = fopen("copy.exe","w");
	while (a != EOF)
	{
		a = fgetc(fp1);
		fputc(a,fp2);
	};
	fclose(fp1);
	fclose(fp2);
}

结果:

Press any key to continue

代码运行后,在目录下 copy.exe 文件与 test.exe 文件的大小不一样


复制二进制文件的正确方法

示例:

void main()
{
	char buf[128];
	int a;
	FILE *fp1, *fp2;
	fp1 = fopen("test.exe","rb");
	fp2 = fopen("copy.exe","wb");
	a = fread(buf,1,128,fp1);		//读取的数据个数
	while (a != 0)
	{
		fwrite(buf,1,128,fp2);
		a = fread(buf,1,128,fp1);
	};
	fclose(fp1);
	fclose(fp2);
}

结果:

Press any key to continue

代码运行后,在目录下 copy.exe 文件与 test.exe 文件的大小一样

改变文件读写位置

文件的读写总是从文件的开头起始,一直读写到最后,但如果文件内容较多,只需要获取文件某指定位置的数据,这种方法就比较麻烦。不能快速获取指定位置数据

文件读取指针

文件读写标记记录访问的位置

示例:

/*将文件 hello world.txt 的内容复制两次到文件 copy.txt 中,两次之间的内容使用空白行分隔*/
#include "stdio.h"
void main()
{
	char buf[10];
	int a;
	FILE *fp1,*fp2;
	fp1 = fopen("hello world.txt","r");
	fp2 = fopen("copy.txt","w");
	a = fread(buf,1,10,fp1);
	while(a != 0)
	{
		fwrite(buf,1,a,fp2);		//size设置读取的最小单元
		a = fread(buf,1,10,fp1);
	}

	//再循环复制一次
	fputc('\n',fp2);
	fputc('\n',fp2);

	rewind(fp1);
	a = fread(buf,1,10,fp1);
	while(a != 0)
	{
		fwrite(buf,1,a,fp2);
		a = fread(buf,1,10,fp1);
	}
	fclose(fp1);
	fclose(fp2);
}

结果:

Press any key to continue

代码运行后在目录下双击并打开文件后会显示文件内容

rewind函数将读写指针重新指向文件开头

rewind(fp)

将fp指向的文件读写指针重新指向文件开头

fseek函数指定文件读写指针位置

fseek(文件指针,位移量,起始点)
/*
起始点:
0	表示文件开始位置
1	表示当前读写指针位置
2	表示文件末尾位置
*/

示例:

#include "stdio.h"
void main()
{
	char buf[10];
	int a;
	FILE *fp1, *fp2;
	fp1 = fopen("a.txt", "r");
	fp2 = fopen("b.txt", "w");
	fseek(fp1,10,0);					//文件指针在文件开头向后移动10个字节位置
    	//fseek(fp1,-10,2);					//文件指针在文件末尾向后移动10个字节位置
	a = fread(buf, 1, 10, fp1);
	while (a != 0)
	{
		fwrite(buf, 1, a, fp2);
		//fseek(fp1, 10, 1);				//文件指针在当前位置向后移动10个字节位置
		a = fread(buf, 1, 10, fp1);
	}
	fclose(fp1);
	fclose(fp2);
}

结果:

Press any key to continue

代码运行后在目录下双击并打开文件后会显示文件内容;当起始位置不同时,文件的内容也会不同

文件操作错误检查

读写文件是否存在错误,除了使用函数的返回值来检验以外,还可以使用错误检查读写函数是否正确执行

ferror函数

ferror(fp)

返回值为"0"表示读写正确;返回值为"1"表示读写错误

clearerr函数

将文件错误标志和文件结束标志置为0。当ferror检查到读写函数出现错误,此时应当立即调用clearerr(fp),使得下一轮能正常使用ferror函数进行检查

示例:

#include "stdio.h"
void main()
{
    char buf[10];
	int a;
	FILE * fp1, *fp2;
	fp1 = fopen("hello world.txt","r");
	fp2 = fopen("copy.txt","w");	
	a = fread(buf,1,10,fp1);
	while(a != 0)
	{
		fwrite(buf,1,a,fp2);	
		a = fread(buf,1,10,fp1);
		printf("%d",ferror(fp1));		//检查fread函数调用是否有误
        if(ferror(fp1)) clearerr(fp1);			//当ferror检查到读写函数出现错误,立即调用clearerr(fp1),使得下一轮能正常使用ferror函数进行检查
    }
	fclose(fp1);
	printf("%d",ferror(fp1));
	fclose(fp2);
}

结果:

00000000000

Press any key to continue

代码运行后在目录下双击并打开文件后会显示文件内容,文件内容为复制内容

标签:fp,文件,txt,fp1,fp2,操作,fopen
From: https://www.cnblogs.com/ruoxianshi/p/17035083.html

相关文章