首页 > 其他分享 >【C语言】文件操作

【C语言】文件操作

时间:2024-06-13 11:32:57浏览次数:17  
标签:文件 NULL int C语言 FILE printf 操作 fopen

1.为什么需要文件操作
2.文件的打开与关闭
3.文件指针
4.文件的打开与关闭
5.fopen
6.函数声明
7.文件的打开方式
8.函数使用
9.fclose
10.函数声明
11.函数使用
12.文件的顺序读写
13.fgetc与fputc
14.函数声明
15.函数使用
16.fgets与fputs
17.函数声明
18.函数使用
19.fscanf与fprintf
20.函数声明
21.函数使用
22.fread与fwrite
23.函数声明
24.函数使用

一.fseek函数——

功能:

参数解析:

 练习1.要求输出字符c

    练习2.要求输出字符f

        A.方法1.采用SEEK_CUR 当前指针指向的位置为中心 。

        B.方法2:SEEK_CUR    文件指针的当前位置为中心。

        C.方法3:SEEK_END    文件结尾为中心。

ftell函数

功能:

rewind函数

功能

代码实践

为什么需要文件操作

文件操作具有以下重要性: 数据永久保存:通过文件操作,我们可以将数据永久保存在硬盘中,即使程序终止或计算机关机,数据仍然可以被保留。 数据共享:通过文件操作,可以将数据保存到文件中,并且可以方便地与其他人共享和传输数据。 数据备份:通过文件操作,可以将重要数据进行备份,以防止数据丢失或损坏。 数据处理:通过文件操作,可以读取文件中的数据并进行处理和分析,从而实现对大批量数据的高效处理和计算。

文件的打开与关闭

fopen:是文件打开库函数

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

fopen在头文件stdio.h中声明

第一个参数类型是const char*。表示要打开的文件标识。
第二个参数类型是const char*。表示打开文件的方式。

返回值类型是FILE*。打开成功时返回这个文件打开后在内存中的文件信息区结构体的地址;打开失败时返会NULL。

 参数(打开方式)                  含义                              

     "r"                 为输入数据,打开一个已经存在的文本文件
     "w"                 为了输出数据,新建一个文本文件            
     "a"                 向文本文件的末尾添加数据                     
     "rb"                为了输入数据,打开一个二进制文件             
     "wb"                为了输出数据,新建一个二进制文件           
     "ab"                向一个二进制文件的末尾添加数据               
     "r+"                为了读写,打开一个文本文件                   
     "w+"                为了读写,新建一个文本文件                 
     "a+"                打开一个文本文件,在文件的末尾进行读写      
     "rb+"               为了读写,打开一个二进制文件                 
     "wb+"               为了读写,新建一个二进制文件
     "ab+"               打开一个二进制文件,在文件末尾读写          
 

首先要说明的是,这里的输入数据是指从文件向内存中输入数据,就是读取数据;输出就是从内存向文件中输出数据,就是写入数据。

​
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
    return 0;
}

​

这段代码中,fopen的第一个参数是"text.txt";第二个参数是"r"。表示在当前目录中以只读的方式打开test.txt文件。if判断,当返回值为NULL时,即打开失败。此时,我们可以使用库函数perror来打印出错的原因。这个库函数的参数可以作为标识。由于没有在这个目录中创建test的文本文件,所以打印出的错误是:没有这样的文件或目录。

fclose

在打开文件后自然需要关闭文件。我们可以使用库函数fclose。

int fclose(FILE*stream)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	fclose(p);
	p = NULL;
	return 0;
}

现在,我已经创建好了一个test.txt文件了,所以能够成功打开。
但是这段代码并没有对这个文件进行读写,所以这个文件中还是空的

文件的顺序读写

刚才的库函数只是打开了某个文件。接下来介绍的这些函数,就可以实现在文件的顺序读写:

fgetc与fputc

fgetc是字符输入函数,适用于所有输入流;fputc是字符输出函数,适用于所有输出流。

fgets有一个参数,类型为FILE*。表示从FILE*指定的流中读取指示符当前的字符到内存中(即将字符输入到内存中)。读取后,标识符向前移动一个字符(这里的标识符可以理解为光标)。返回值类型是int。如果读取成功,返回这个字符的ASCII码值;读取失败,返回EOF。

fputc有两个参数:
第一个参数的类型是int。表示要输出的字符的ASCII码值;
第二个参数的类型是FILE*。表示要将这个字符输出到FILE*指定的流中。
输出后,标识符向前移动一个字符。返回值类型为int。如果输出成功,返回这个字符的ASCII码值;输出失败,返回EOF。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputc('a', p);
	fclose(p);
	p = NULL;
	return 0;
}

这段代码使用了"w"输出的方式在当前目录中打开了一个text.txt文件,然后判断是否打开成功,使用fputc函数在这个文本文件中写入字符a。最后关闭文件。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	/*fputc('a', p);*/
	int a=fgetc(p);
	printf("%c", a);
	fclose(p);
	p = NULL;
	return 0;
}

使用只读"r"的方式打开当前目录中的text.txt文件,并判断是否打开成功,文件中的字符字符依次存储到int型的变量a中并打印。最后关闭文件。

fgets与fputs

fgets是文本行输入函数,适用于所有输入流;fputs是文本行输出函数,适用于所有输出流。

fgets有三个参数:
第一个参数类型为char*。表示将指定流中的字符串输入到的空间的首地址;
第二个参数类型为int。表示读取的字符的个数;
第三个参数类型为FILE*。表示从FILE*指定的流中读取指示符当前的num个字符到str指向的空间中(即将字符串输入到内存中)。读取后,标识符向前移动num个字符。

fputs有两个参数:
第一个参数类型为const char*。表示要输出到指定流的字符串;
第二个参数类型为FILE*。表示将str指向的字符串中的内容输出到FILE*指定的流中。输入后,标识符向后移动到字符串的末尾。
需要注意的是,fputs输出字符串的结束标志是’\0’,并且在输出字符串时不输出’\0’。返回值类型为int。输出成功时返回一个非负值;输出失败时,返回EOF。

函数使用

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("I am a student", p);
	fclose(p);
	p = NULL;
	return 0;
}

在这段代码中:
首先以"w"的方式在当前目录中打开text.txt文件,并判断是否打开成功("w"的方式打开文件实际上是创建一个新的文件)。再讲字符串使用fputs输入到text.txt中。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20] = { 0 };
	int a=fgets(arr, 5, p);
	printf("%s", a);
	fclose(p);
	p = NULL;
	return 0;
}

需要注意的是,创建的用于存储字符串的数组大小不能小于一次读取的量,否则就会出现数组越界的问题。

fscanf与fprintf

fscanf是格式化输入函数,适用于所有输入流;fprintf是格式化输出函数,适用于所有输出流。

其实这两个函数可以与我们熟知的scanf与printf函数结合理解:
scanf是从标准输入流输入格式化的数据到内存;printf是将格式化的数据以标准输出流的方式输出。
而fscanf可以将所有输入流的数据格式化的输入到内存;fprintf可以将内存中的数据格式化的输出到任何输出流。

标准输入流就是键盘,标准输出流就是屏幕。而我们今天所介绍的文件也是一种流。只不过标准输入流与标准输出流在程序运行的时候系统会自动打开,而其他的流需要我们自己打开。例如我们通过fopen打开一个文件流。

格式化就是整型的格式、浮点型的格式、字符的格式、字符串的格式等。我们用"%d"输出就是按照有符号的十进制整型输出;用"%c"输出就是按照字符输出;用"%s"输出就是按照字符串输出。

函数声明

这两个函数在声明在头文件stdio.h中:

函数使用

在使用时,也是与scanf、printf类似,只是前面需要指定流。

例如将数据格式化的输出到文件流:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	fprintf(p, "%s", "abcde");
	fclose(p);
	p = NULL;
	
	return 0;
}

将文件流中的数据格式化的输入到内存中:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	/*fprintf(p, "%s", "abcde");*/
	char arr[10] = { 0 };
	fscanf(p, "%s", arr);
	printf("%s ", arr);
	fclose(p);
	p = NULL;
	
	return 0;
}

fread与fwrite

fread是二进制输入函数,只适用于文件流;fwrite是二进制输出函数,只适用于文件流。

函数声明

这两个函数在声明在头文件stdio.h中

fwrite

fwrite有4个参数:
第一个参数类型为void*。表示将这个ptr指针指向的空间中的元素写入文件(void*可以接收任意类型的指针变量);
第二个参数类型为size_t(无符号整型)。表示输出的每个元素的大小;
第三个参数类型为size_t。表示输出count个大小为size的元素;
第四个参数类型为FILE*。表示将数据输出到指定的FILE*文件流中。

返回值为size_t。返回成功写入的元素总数。
如果此数字与 count 参数不同,则写入错误阻止函数完成。
如果大小或计数为零,则该函数返回零。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "wb");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[20] = { 1,2,3,4,5,6,7,8,9,10 };
	for (int i = 0; i < 10; i++)
	{
		fwrite(arr+i, sizeof(int), 1, p);
    }
	fclose(p);
	p = NULL;
	
	return 0;
}

由于fwrite是用于在二进制文件中写入数据,所以在打开文件时需要使用"wb"的方式。
并且在使用记事本打开时是无法读取的,所以是乱码。

当我们再使用二进制的方式读取时,即可获得其数据:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "rb");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	/*int arr[20] = { 1,2,3,4,5,6,7,8,9,10 };
	for (int i = 0; i < 10; i++)
	{
		fwrite(arr+i, sizeof(int), 1, p);
    }*/
	int n = 0;
	for (int i = 0; i < 10; i++)
	{
		int a = fread(&n, sizeof(int), 1, p);
		printf("%d ", n);
}
	fclose(p);
	p = NULL;
	
	return 0;

在这篇文章中我们了解了文件的打开与关闭、文件的顺序读写的相关函数。
其实有一些内容是没有介绍到的。比如当读写结束后原因的判断,到底是因为读写到了末尾,还是读写错误;比如二进制文件与文本文件;比如文件的随机读写等一些相关内容。

fseek函数

 1. 功能:

根据文件指针的位置和偏移量来定位文件指针。(只用来:定位!!!

2.参数解析:
fseek第一个参数为流,第二个参数为偏移量,第三个参数为文件指针定位的位置
                        SEEK_SET    以文件开头为中心
                        SEEK_CUR    文件指针的当前位置为中心
                        SEEK_END    文件结尾为中心

不适用fseek:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	int a = 0;
	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a);
	fclose(p);
	p = NULL;
	
	return 0;
}

代码讲解:字符输出函数——fgetc(),一次读取一个字符。使用fgetc函数时,第一次指针只能指向开头位置,每使用一次fgetc才能读取一个字符,指针会逐步向后,这种方法很死板,不能随心所欲的想指向哪个文件内容就指向哪个。

使用fseek:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}/*
	int a = 0;*/
/*	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a)*/;
	fseek(p, 2, SEEK_SET);
	int a=fgetc(p);
	printf("%c ", a);
	fclose(p);
	p = NULL;
	
	return 0;
}

代码讲解: fseek(pf, 2, SEEK_SET);

                这句代码意为:将文件指针指向文件内容开头位置,偏移量为2,偏移量0代表a,2代表0+2,即文件指针指向a之后的第2个字符c。

二.ftell函数

long int ftell ( FILE * stream );

1.功能:

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

ftell的使用:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}/*
	int a = 0;*/
/*	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a)*/;
	fseek(p, 2, SEEK_SET);
	int a=fgetc(p);
	printf("%c\n", a);
	printf("%d\n", ftell(p));

	fseek(p, -2, SEEK_END);
	int b = fgetc(p);
	printf("%c\n", b);	
	printf("%d\n", ftell(p));
	fclose(p);
	p = NULL;
	
	return 0;
}

三.rewind函数

1.功能:

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

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
	FILE* p = fopen("text.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}/*
	int a = 0;*/
/*	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a);
	a = fgetc(p);
	printf("%c\n", a)*/;
	fseek(p, 2, SEEK_SET);
	int a=fgetc(p);
	printf("%c\n", a);
	printf("%d\n", ftell(p));
	rewind(p);
	printf("%d\n", ftell(p));
	fseek(p, -2, SEEK_END);
	int b = fgetc(p);
	printf("%c\n", b);	
	printf("%d\n", ftell(p));
	rewind(p);
	printf("%d\n", ftell(p));
	fclose(p);
	p = NULL;
	
	return 0;
}

标签:文件,NULL,int,C语言,FILE,printf,操作,fopen
From: https://blog.csdn.net/hhj25802580/article/details/139644283

相关文章

  • java+vue3+el-tree实现树形结构操作
    基于springboot+vue3elementPlus实现树形结构数据的添加、删除和页面展示效果如下代码如下,业务部分可以自行修改java后台代码importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper;importcom.daztk.mes.common.annotation.LogOperation;import......
  • cwRsync小小的工具大大的坑——windows文件同步工具
    *cwRsync是linux工具:Rsync,在windows上的版本两台windos主机之间的某个或多个目录进行同步,源端安装服务端,目标端安装客户端下载地址:cwRsync:cwRsync文件同步工具下载内容如下cwRsyncServer_4.0.5_Installer.zip为服务端软件cwRsync_4.0.5_Installer.zip为客户端软件服......
  • 10.C语言for循环和跳出循环的知识点
    C语言for循环、continue和break知识点3.13for循环3.14for的一些用法3.15continue和break的作用3.16嵌套的规律3.17—作业3.13for循环概述和while的对比#include<stdio.h>intmain(){ intdata; //for(条件附初值;判断临界点;条件改变)//判断、执行循......
  • uniapp 随笔 各位同学如果uniapp有问题,请留言,我有时间,我会去做一下,将解答的操作会
    1. up-popup弹窗后禁止底层的页面继续滚动   直接在u-popup包一个view然后加上一个方法@touchmove.stop.prevent="prevent"  然后在方法prevent加一个空方法就行了  代码如下:     <viewclass="my"@touchmove.stop.prevent="prevent">  ......
  • 数据密集型企业是如何选择替代FTP传输文件的系统的?
    数据密集型企业是指其发展和运行高度依赖于数据、算法和算力的闭环优化体系的企业。这类企业拥有规模化知识创造者、更广泛的智能工具以及更丰裕的数据要素资源。毋庸置疑,数据对于数据密集型企业来说是最关键、最核心的资产,但数据密集型企业同样也面临着数据使用上的挑战:数据安......
  • 企业文件外发安全面临着来自多方的挑战,该如何有效应对?
    企业文件外发是最普遍的文件流转场景之一,企业与外部供应商、合作方、客户等进行文件往来,是保证业务有序正常开展的基础。在日常中,企业常用的文件外发方式包括邮箱、QQ、微信、FTP应用、网盘等。这些方式虽然一定程度解决了文件外发需求,但在文件外发安全上却存在多方面的隐患,具体......
  • 企业跨境文件传输的核心痛点,怎样保证稳定可靠的传输性能?
    随着经济和国际贸易的发展,企业跨境文件传输日趋频繁,多个行业均存在高频且大量的跨境文件传输需求:跨境电子商务:跨境电商平台需要进行跨国的订单、支付和物流信息的传输,以便顺利完成交易和配送。涉及跨国企业的内部沟通、订单管理、跨境电商的订单处理等。金融服务:跨境银行转账......
  • 列出并排序文件系统根目录(/)下各个目录的大小
    du-sh/*|&grep-v"du:"|sort-hrdu:是一个用于估计文件和目录磁盘使用空间的命令。-s:表示总结,只显示每个指定目录的总大小。-h:表示“human-readable”,即以易读的格式(如K,M,G)显示大小。/:这是一个通配符,它匹配根(/)下的所有目录。因此,du-sh/会列出根目录下所......
  • 用于将字节进行base64编码或解码(C语言实现)
    V1.02024年6月13日发布于博客园目录base64.hbase64.c基本原理见代码注释!base64.h#ifndef_BASE64_H#define_BASE64_H/***@filename:base64.h*@brief:用于将字节进行base64编码或解码*@author:[email protected]*@date:2024年6......
  • Java学习 - MySQL数据增删更清操作 实例
    INSERTINTO-插入语法1-【常用;支持多行;可用于子查询】INSERTINTO表名(字段列表)VALUES(字段值列表),(字段值列表),(字段值列表),(字段值列表);注意如果想设置空值,可以用NULL表示字段列表和字段值列表必须一一对应字段列表的顺序可以和表定义顺序不同可以省略......