C语言中的文件操作指南

news2024/11/26 12:24:43

阅读导航

  • 前言
  • 一、文件类型
    • 1. 程序文件
    • 2. 数据文件
    • PS.文件名
  • 二、文件的打开和关闭
    • 1. 文件指针
    • 2. 文件的打开和关闭
  • 三、文件的顺序读写
  • 四、文件的随机读写
    • 1. fseek() 函数
    • 2. ftell() 函数
    • 3. rewind() 函数
  • 总结

前言

在C语言中,文件操作是一项重要的任务。通过文件操作,我们可以读取和写入文件的内容,实现数据的长期存储和共享。文件操作不仅可以用于文本文件,还可以用于二进制文件、配置文件等各种类型的文件。

这篇文章中,我们将深入探讨C语言文件操作的各个方面,介绍常用的文件操作函数和技巧,帮助读者更好地理解和应用文件操作。无论是初学者还是有一定经验的开发者,都能从中获得实用的知识和技能,为自己的C语言编程之路增添新的可能性。

一、文件类型

1. 程序文件

⭕程序文件是包含C源代码的文件,它们经过编译和链接后可以生成可执行程序。程序文件中定义了变量、函数、结构体等程序元素,通过编写相应的代码实现所需的功能。在程序文件中,我们可以使用各种控制结构、输入输出函数和库函数来操作和处理数据。

2. 数据文件

⭕数据文件是包含实际数据的文件,可以是文本文件或二进制文件。文本文件以可读的文本形式存储数据,可以使用标准的输入输出函数(如printf和scanf)来读取和写入文本文件。二进制文件以二进制形式存储数据,一般需要使用专门的读写函数进行处理。

PS.文件名

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

在这里插入图片描述

二、文件的打开和关闭

1. 文件指针

文件指针是C语言中用于定位和访问文件的机制。它是一个特殊的变量,用来指示当前操作的位置或位置的偏移量。通过文件指针,我们可以进行读写操作,并在文件中移动指针的位置。

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名FILE.

struct _iobuf {
		char *_ptr;
		int   _cnt;
		char *_base;
		int   _flag;
		int   _file;
		int   _charbuf;
		int   _bufsiz;
		char *_tmpfname;
		};
typedef struct _iobuf FILE;

不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异

文件指针的位置决定了下一次读写操作的位置。例如,在读取文件内容时,每次读取前文件指针会自动后移,以便下次读取从下一个位置开始。

另外,文件指针还有几个重要的特殊位置:

  • 文件起始位置(0):文件打开后,文件指针通常位于文件起始位置,即偏移量为0的位置。

  • 文件末尾位置(EOF):表示文件的结尾,文件指针在读取到文件末尾时会自动停止读取操作。

  • 文件错误位置(NULL):在发生错误时,文件指针可能为NULL,表示无法继续操作文件。
    在这里插入图片描述

在使用文件指针时,我们需要注意一些常见的问题。首先,操作文件前必须确保文件已经成功打开,并在使用完毕后及时关闭文件,以便释放资源。其次,应注意异常情况的处理,如文件不存在、权限不足等,以避免程序崩溃或产生错误结果。

2. 文件的打开和关闭

文件的打开和关闭是文件处理中非常重要的操作。在进行文件读写时,必须先打开文件,然后进行读写操作,最后再关闭文件。这样做可以避免文件资源泄漏和数据损坏等问题。

在C语言中,文件的打开和关闭可以通过文件操作函数来实现。其中,常用的文件操作函数包括fopenfclose等。下面是一个基本的文件打开和关闭的示例:

#include <stdio.h>

int main()
{
    FILE *fp;
    char filename[20];
    // 打开文件
    printf("请输入要打开的文件名:");
    scanf("%s", filename);
    fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("文件打开失败!\n");
        return 1;
    }
    printf("文件打开成功!\n");
    // 文件读取或写入操作…
    // 关闭文件
    fclose(fp);
    printf("文件已关闭!\n");
    return 0;
}

上述代码中,我们首先定义了一个指向文件的指针(FILE *fp),然后通过fopen函数打开文件。fopen函数的第一个参数是文件名或路径(字符串类型),第二个参数是打开文件的模式(字符串类型)。文件打开模式包括:

文件使用方式含义如果指定文件不存在
“r” (只读)为了输入数据,打开一个已经存在的文本文件出错
“w” (只写)为了输出数据,打开一个文本文件建立一个新的文件
“a” (追加)向文本文件尾添加数据建立一个新的文件
“rb” (只读)为了输入数据,打开一个二进制文件出错
“wb” (只写)为了输出数据,打开一个二进制文件建立一个新的文件
“ab” (追加)向一个二进制文件尾添加数据出错
“r+” (读写)为了读和写,打开一个文本文件出错
“w+” (读写)为了读和写,建议一个新的文件建立一个新的文件
“a+” (读写)打开一个文件,在文件尾进行读写建立一个新的文件
“rb+” (读写)为了读和写打开一个二进制文件出错
“wb+” (读写)为了读和写,新建一个新的二进制文件建立一个新的文件
“ab+” (读写)打开一个二进制文件,在文件尾进行读和写建立一个新的文件

在打开文件后,我们可以进行读写操作。最后通过fclose函数关闭文件,以释放资源。如果在打开文件时出现错误,则返回的指针为NULL,需要进行错误处理。

三、文件的顺序读写

当打开文件时,可以通过指定不同的访问模式来控制文件读写的方式。在选择读写模式后,就可以使用文件指针进行读写操作。

⭕常见的读写函数有:

功能函数名适用于
字符输入fgetc所有输入流
字符输出fputc所有输出流
文本行输入fgets所有输入流
文本行输出fputs所有输出流
格式化输入fscanf所有输入流
格式化输出fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件

下面是一个示例代码,用于在文本文件中按顺序读取和写入数据:

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    char str[255];
    if (fp == NULL) {
        printf("Error opening file\n");
        return -1;
    }

    // 读取每一行并输出
    while (fgets(str, 255, fp) != NULL) {
        printf("%s", str);
    }

    fclose(fp);

    // 向文件中写入数据
    fp = fopen("example.txt", "a");
    if (fp == NULL) {
        printf("Error opening file\n");
        return -1;
    }
    fprintf(fp, "This is a new line\n");
    fclose(fp);

    return 0;
}

该示例程序首先以只读模式打开文件 example.txt,然后使用 fgets 函数按照行读取数据并输出。接着,它再以追加模式打开同一个文件,并使用 fprintf 函数向文件中写入一行新数据。

四、文件的随机读写

1. fseek() 函数

fseek 是一个用于设置文件指针位置的函数。它的原型如下:

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

参数说明:

  • stream:指向要设置位置的文件流的指针。
  • offset:要添加到或减去当前位置的字节数,可以是正数或负数。
  • origin:用于确定 offset 如何解释的常量。可以使用以下值之一:
    • SEEK_SET:从文件开头开始计算偏移量。
    • SEEK_CUR:从当前位置开始计算偏移量。
    • SEEK_END:从文件末尾开始计算偏移量。

返回值为 0 表示成功,非零值表示出错。

使用 fseek 可以将文件指针定位到文件中的任意位置进行读写操作。例如,要将文件指针定位到文件开头,可以使用如下代码:

FILE *fp = fopen("example.txt", "r");
if (fp == NULL) {
    printf("Error opening file\n");
    return -1;
}

// 将文件指针设置到文件开头
fseek(fp, 0, SEEK_SET);

// 在此处进行读取操作

fclose(fp);

在上述代码中,我们打开了一个名为 example.txt 的文件,并将文件指针通过 fseek 函数定位到了文件的开头位置。

2. ftell() 函数

ftell 是一个用于获取文件指针当前位置的函数。它的原型如下:

long ftell(FILE* stream);

参数 stream 是指向要获取当前位置的文件流的指针。返回值是当前位置相对于文件开头的字节数(偏移量)

以下是一个示例代码,演示了如何使用 ftell 函数获取文件指针的当前位置:

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp == NULL) {
        printf("Error opening file\n");
        return -1;
    }

    // 定位到文件第6个字节的位置
    fseek(fp, 5, SEEK_SET);

    // 获取文件指针的当前位置
    long position = ftell(fp);
    printf("Current position: %ld\n", position);

    fclose(fp);

    return 0;
}

在上述示例中,我们首先打开一个名为 example.txt 的文件,并使用 fseek 将文件指针定位到文件的第6个字节处。然后,通过调用 ftell 函数获取文件指针的当前位置,并将其打印出来。

🚨🚨注意:ftell 返回的是一个 long 类型的值,表示当前位置相对于文件开头的字节数。如果发生错误,ftell 可能会返回一个特殊的值 EOF(-1)。因此,在使用 ftell 的结果时,应该先检查是否出错。

3. rewind() 函数

rewind 是一个用于将文件指针重新定位到文件开头的函数。它的原型如下:

void rewind(FILE *stream);

参数 stream 是指向要重新定位的文件流的指针。rewind 函数会将文件指针移动到文件开头,即相当于调用 fseek(stream, 0, SEEK_SET)

以下是一个示例代码,演示了如何使用 rewind 函数将文件指针重新定位到文件开头:

#include <stdio.h>

int main() {
    FILE *fp = fopen("example.txt", "r");
    if (fp == NULL) {
        printf("Error opening file\n");
        return -1;
    }

    // 将文件指针重新定位到文件开头
    rewind(fp);

    // 在此处进行读取操作

    fclose(fp);

    return 0;
}

在上述示例中,我们打开一个名为 example.txt 的文件,然后使用 rewind 将文件指针重新定位到文件开头。这样,在之后的读取操作中,可以从文件的开头开始读取数据。

总结

本文介绍了 C 语言中文件操作的基础知识,包括文件类型、文件的打开和关闭、文件的顺序读写和随机读写等。文章首先将文件分为程序文件和数据文件两种类型,并简要说明了它们的区别以及命名方式。接下来,文章详细讲解了文件的打开和关闭过程,包括如何使用文件指针和相关函数打开文件、关闭文件,以及处理错误情况。在讲解完文件的基础操作后,文章介绍了文件的顺序读写和随机读写两种方式,并提供了相应的函数及示例代码进行演示。其中,随机读写部分还详细介绍了 fseek()、ftell() 和 rewind() 等函数的用法。

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

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

相关文章

20和遍历以及迭代器有关的一些东西

知识点有点散&#xff0c;只能这样记录了 1、这边是和遍历有关的&#xff1a; class Person:def __init__(self):self.result 1def __getitem__(self, item):self.result 1if self.result > 6:raise StopIteration(停止遍历)return self.resultpassp Person() for i in…

Unity中Shader光照模型Phong的实现

文章目录 前言一、对主平行光实现高光效果1、在属性面板定义高光颜色2、在属性面板定义高光系数3、在属性面板定义高光范围系数4、获取 V (模型顶点的世界坐标 指到 相机世界坐标 的单位向量)5、由上一篇推理出的公式得到  R 向量6、由公式计算得出高光效果 二、使用已有的数…

常用的软件项目管理工具一览

软件项目管理工具是帮助团队成功管理和完成软件开发项目的软件程序和应用程序。根据项目及其规模和复杂性&#xff0c;可以使用各种各样的这些工具来协助完成任务&#xff0c;从任务跟踪和调度&#xff0c;到项目报告&#xff0c;到版本控制和协作。 项目经理对软件项目的整体成…

Git 回退代码的两种方法对比

Git 回退代码版本 在项目的开发中&#xff0c;有时候还是会出现&#xff0c;一些误提交了一些代码&#xff0c;这时候就会想撤回提交的代码&#xff0c;在Git中有两种方法可以使用&#xff0c;现在通过对比方法比较这两种方法的区别&#xff0c;分别适用于哪些情况&#xff1f…

Google zxing 生成带logo的二维码图片

环境准备 开发环境 JDK 1.8SpringBoot2.2.1Maven 3.2 开发工具 IntelliJ IDEAsmartGitNavicat15 添加maven配置 <dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.0</version> </…

Stm32_标准库_12_串口_发送数据

波特率&#xff1a;约定的传输速率&#xff0c;1000bps,1s发1000位 引脚 结构 数据帧的传输特点 代码&#xff1a; #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h"GPIO_InitTypeDef GPIO_InitStruct; USART…

计算机毕业设计选什么题目好?springboot 学习笔记系统

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

【互联网】实习一个月感受

说明&#xff1a;岗位&#xff1a;golang开发实习生&#xff0c;实习已经一个月多点了&#xff0c;这篇文章谈谈实习应该注意些什么点&#xff0c;以及该做些什么事情 说实话这不是我第一次实习了&#xff0c;但是感受很深 注意点&#xff1a; 1、没事找话说 比如中午和同事吃…

12.JVM

一.JVM类加载机制:把类从硬盘文件加载到内存中 1.java文件,编写时是一个.java文件,编译后现成一个.class的字节码文件,运行的时候,JVM就会读取.class文件,放到内存中,并且构造类对象. 2.类加载流程: a.加载:找到.class文件,打开文件,读取内容,尝试解析文件内容. b.验证:检查…

【Python学习笔记】字符串

1. 字符串定义 可以用双引号 、 单三引号、双三引号&#xff0c;下面的定义都是正确的 "你好" 你好 """你好"""其中三引号可以 直接写内容有多行 的字符串。如下 letter 刘总&#xff1a;您好&#xff01;您发的货我们已经收到&am…

百度开放平台第三方代小程序开发,授权事件、消息与事件通知总结

大家好&#xff0c;我是小悟 关于百度开放平台第三方代小程序开发的两个事件接收推送通知&#xff0c;是开放平台代小程序实现业务的重要功能。 授权事件推送和消息与事件推送类型都以event的值判断。 授权事件推送通知 授权事件推送包括&#xff1a;推送票据、授权成功、取…

【C++进阶】:特殊类的设计

特殊类的设计 一.设计一个类不能被拷贝二.设计一个类只能在堆上创建对象三.设计一个类只能在栈上创建4.设计一个类不能被继承五.设计一个类只能有一个对象(单例模式) 一.设计一个类不能被拷贝 拷贝只会放生在两个场景中&#xff1a;拷贝构造函数以及赋值运算符重载&#xff0c…

蓝桥杯(跳跃 C++)

思路&#xff1a; 1、根据题目很容易知道可以用深度搜索、广度搜索、动态规划的思想解题。 2、这里利用深度搜素&#xff0c;由题目可知&#xff0c;可以往九个方向走。 3、这里的判断边界就是走到终点。 #include<iostream> using namespace std; int max1 0; int …

Vue3中ref创建的引用为什么一定要用.value来获取值

Vue3中ref创建的引用为什么一定要用.value来获取值 回顾jsjs中修改复制变量,改变原始变量vue3中使用ref 回顾js js中一个变量赋值给另一个变量,改变另一个变量,原始变量不变 let a 0; let b a; b 2 console.log("a: "a);js中修改复制变量,改变原始变量 let obj…

【Java 进阶篇】JavaScript 中的全局对象和变量

JavaScript 是一门非常强大的编程语言&#xff0c;它提供了许多全局对象和变量&#xff0c;以便于在整个应用程序中共享数据和功能。本文将详细介绍 JavaScript 中的全局对象和变量&#xff0c;包括全局对象、全局变量、全局函数以及它们的用途和示例。 全局对象 JavaScript …

15.项目讲解之前端页面的实现

项目讲解之前端页面的实现 本项目前端使用HBuilerX软件编写HBuilderX下载安装配置一键直达&#xff0c; uniapp框架uniapp官网&#xff0c; 使用Element-ui组件Element-ui组件网址进行前端页面的完成。 前端项目下载地址 前端项目 前端项目展示 首页 首页展示 echarts实现…

9.Linear Maps

线性映射 线性映射是将向量作为输入并产生一些新向量作为输出的转换。 从坐标定义开始(数组)&#xff0c;再到2&#xff0c;3&#xff0c;并展示它们是如何关联的 线性映射的坐标表示最终是矩阵&#xff0c; 1.坐标定义&#xff08;数组&#xff09; 列向量是向量的坐标表示…

iOS- flutter flavor 多环境Configurations配置

一、点击PROJECT的Runner&#xff0c;选择Info选项&#xff0c;在Configurations下方的号添加不同环境的配置&#xff0c;如下图&#xff1a; 二、选择TAGETS的Runner项目&#xff0c;选择Build Settings选项&#xff0c;在输入框输入package&#xff0c;为不同环境配置相应的…

结构体对齐规则

1.第一个成员在结构体变量偏移量为0的地址处。 2.其他成员变量对齐到某个数字(对齐数)的整数倍的地址处。(对齐数编译器默认的一个对齐数与该成员大小的较小值&#xff09;注意&#xff1a;目前有且只有VS编译器有默认为8. 3.结构体总大小为最大对齐数的整数倍。 4.如果嵌套…

快速修复“找不到xinput1_3.dll无法继续执行此代码的”问题的5个方法

在计算机系统中&#xff0c;DLL&#xff08;动态链接库&#xff09;是一个重要的组件&#xff0c;它负责在程序和操作系统之间进行有效的通信。然而&#xff0c;有时候我们可能会遇到“xinput1_3.dll”文件出现问题的情况&#xff0c;这可能会导致系统不稳定甚至无法正常运行。…