【C语言--------文件操作】

news/2025/1/15 14:52:00/

一.文件的概念

为什么使用文件?

如果没有文件,我们写的程序数据是存储在电脑的内存中的,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存,我们可以使用文件。

什么是文件?

磁盘(硬盘)上的文件就是文件。但是在程序设计中,我们一般谈的文件有两种:程序文件

和数据文件(从文件功能的角度来分类的)。


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

数据文件:文件的内容不一定是程序,而是程序运行时的读写数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。

二.二进制文件和文本文件

二进制文件:数据在内存中以二进制的形式存储,如果不加转换的输出到外存的文件中,就是二进制文件。

文本文件如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

      一个数据在文件中的存储:字符型数据在内存中都是以ASCII形式存储的,数值类型既可以字符类型数据的存储方式,也可以采用二进制的存储方式。

三.文件的打开和关闭

         在学习文件的打开和关闭之前,我们得先了解流和标准流。

       

          程序中数据需要输出到各种外部设备,也需要从各种外部设备输入数据,不同的外部设备的输入和输出的操作不相同,为了方便对于各种设备的操作,我们就抽象出了流这个概念。我们可以将流想象成流淌着的字符的河。


        标准流:在C语言程序启动的时候,默认打开了三个流。

stdin-标准输入流,在大多数的环境中,从键盘输入,scanf函数就是从你标准输入流中读取数据。

stdout-标准输出流,在大多数据环境下,输出至显示器界面,printf函数就是将信息输出到标准输出流当中。

stderr-标准错误流,大多数环境中输出到显示器界面。

以上这三个流的类型都是FILE*,通常称为文件指针(文件类型指针)。

C语言中就是通过FILE*的文件指针来维护流的各种操作的。通过文件指针就可以间接找到与他相关联的文件。

在文件读写之前,应该先打开文件,在结束之后关闭文件。

//打开文件
FILE* fopen(contst char* filename, const char* mode);
//关闭文件
FILE* fclose(const char* filename);

mode表示文件的打开模式,"r"(只读),"w"(只写),"a"(追加),"rb"(只读),"wb"(只写)等。

同时也要注意如果指定文件不存在的可能出错。

#include <stdio.h>
int main()
{FILE* pfile;//打开文件pfile = fopen("myfile.txt", "w");//文件操作if (pfile != NULL){fputs("fopen example", pfile);fclose(pfile);}return 0;
}

四.文件的顺序读写

fgetc——字符输入函数。(适用于所有输入流)

fputc——字符输出函数。(适用于所有输出流)

fgets——文本输入函数。(适用于所有输入流)

fputs——文本输出函数。(适用于所有输出流)

fscanf——格式化输入函数。(适用于所有输入流)

fprintf——格式化输出函数。(适用于所有输入流)

fread——二进制输入。(文件输入流)

fwrite——二进制输出。(文件输出流)

上面所说的适用于所有输入流指的是一般适用于标准输入流和其他输入流(如文件输入流);所有的输出流指的是一般适用于标准输出流和其他输出流(如文件输出流)。

五.文件的随机读写

1.fseek

根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)。

int fseek(FILE* stream, long int offset, int origin);

例子:

#include <stdio.h>
int main()
{FILE* pfile;pfile = fopen("example.txt", "wb");fputs("This is an apple.", pfile);fseek(pfile, 9, SEEK_SET);fputs("sam", pfile);fclose(pfile);return 0;
}

2. ftell

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

long int ftell(FILE* stream);

例子:

#include <stdio.h>
int main()
{FILE* pfile;long size;pfile = fopen("myfile.txt", "rb");if (pfile == NULL)perror("error opening file");else{fseek(pfile, 0, SEEK_END);size = ftell(pfile);fclose(pfile);printf("size of myfile.txt:%ld bytes.\n",size);}return 0;
}

 rewind

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

void rewind(FILE*stream)

例子:

#include <stdio.h>
int main()
{int n;FILE* pfile;char buffer[27];pfile = fopen("myfile.text", "w+");for (n = 'A'; n <= 'Z'; n++)fputc(n, pfile);rewind(pfile);fread(buffer, 1, 26, pfile);fclose(pfile);buffer[26] = '\0';printf(buffer);return 0;
}

六.文件读取结束

feof的作用

当文件读取结束的时候,判断读取结束的原因是否为:遇到文件末尾结束。

PS:不能用feof的返回值来判断文件是否结束。

1.文本文件是否读取结束

判断返回值是否为 EOF (fgetc)或者NULL(fgets)

例如:

fgetc 判断是否为EOF

fgets 判断是否为NULL.

eg:

#include <stdio.h>
#include <stdlib.h>
int main()
{int c;FILE* 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);return 0;
}

2.二进制文件的读取结束判断

判断返回值是否小于实际要读取的个数。

例如:

fread判断返回值是否小于实际要读取的个数。

eg:

#include <stdio.h>
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);fclose(fp);double b[SIZE];fp = fopen("test.bin", "rb");size_t ret_code = fread(b, sizeof(*b), SIZE, fp);//读double 的数组if (ret_code){puts("Array read successfully ,contents:");for (int i = 0; i < SIZE; i++)printf("%f ", b[i]);putchar('\n');}else{if (feof(fp))printf("error reading test .bin:unexpecxted end of file \n");else if (ferror(fp))perror("errror reading test.bin");}fclose(fp);
}

七.文件缓冲区

ANSIC标准采用 “缓冲文件系统” 处理数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。

从   内存   向    磁盘  输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。

如果从   磁盘   向   计算机     读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。

缓冲区的大小根据C编译系统决定的。

C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。

如有错误还望指出!

优质内容不断更新!! 


http://www.ppmy.cn/news/1457272.html

相关文章

CMakeLists.txt语法规则:条件判断中表达式说明一

一. 简介 前面学习了 CMakeLists.txt语法中的 部分常用命令&#xff0c;常量变量&#xff0c;双引号的使用。 前面一篇文章也简单了解了 CMakeLists.txt语法中的条件判断&#xff0c;文章如下&#xff1a; CMakeLists.txt语法规则&#xff1a;条件判断说明一-CSDN博客 本文…

Python实战开发及案例分析(11)—— b树

B树&#xff08;B-Tree&#xff09;是一种自平衡的树数据结构&#xff0c;它允许高效地进行查找、插入、删除等操作&#xff0c;广泛应用于数据库和文件系统。B树的每个节点可以包含多个键&#xff0c;并且有多个子节点。B树的关键特点包括&#xff1a; 每个节点可以有多个子节…

MYSQL-使用事务保证数据完整性

什么是事务&#xff1f; 事务&#xff08;Transaction&#xff09;是作为单个逻辑工作单元执行的一系列操作 多个操作作为一个整体向系统提交&#xff0c;要么都执行&#xff0c;要么都不执行 事务的特性&#xff1a; 事务必须具备以下四种属性&#xff0c;简称ACID属性 1、…

Quora 首席执行官亚当·德安杰洛 (Adam D’Angelo) 谈论了 AI、聊天机器人平台 Poe,以及 OpenAI 为什么不是竞争对手

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Linux学习之IP协议

前言&#xff1a; 在学习IP协议i前&#xff0c;我们其实知道网络协议栈是一层层的&#xff0c;上层封装好之后就传给下层&#xff0c;对于我们正要学习到的TCP协议&#xff0c;在对数据进行封装之后&#xff0c;并不是直接就将数据进行传输&#xff0c;而是交给下一层网络层进…

本科生毕业设计答辩模板

答辩模板一&#xff1a;学术性答辩模板 尊敬的各位评委老师&#xff1a; 大家好&#xff01;我是来自XX大学的学生XXX。今天我将就我的毕业论文《XXXXXX》进行答辩。我选择这个主题进行研究的动机是……&#xff0c;这主要体现在以下几个方面&#xff1a;…… 在准备论文的过程…

Redis 入坑基本指南

引言 本指南将帮助您了解如何安装、配置和基本使用 Redis。Redis 是一款开源的高性能键值存储系统&#xff0c;可用于缓存、数据库、消息中间件等多种用途。 1. 安装 Redis a. 下载 Redis&#xff1a; 可以从 Redis 官方网站&#xff08;https://redis.io&#xff09;下载最…

部署YUM仓库以及NFS共享服务

YUM仓库部署 一.YUM概述 YUM仓库源是一种软件包管理工具&#xff0c;用于在Linux系统上安装、更新和删除软件包。YUM仓库源包含了软件包的元数据信息和实际的软件包文件。用户可以通过配置YUM仓库源&#xff0c;从中下载和安装软件包。 常见的YUM仓库源包括&#xff1a; 本…