C进阶-语言文件操作

news2024/11/18 7:37:31

本章重点:

什么是文件
文件名
文件类型
文件缓冲区
文件指针
文件的打开和关闭文件的顺序读写文件的随机读写文件结束的判定

 1.  什么是文件

磁盘上的文件是文件。
但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件

 1.1 程序文件

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

 1.2 数据文件

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

 1.3 文件名

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

 2. 文件的打开和关闭

 2.1 文件指针

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。

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

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

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

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关

心细节。

一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

下面我们可以创建一个FILE*的指针变量:

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

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

2.2 文件的打开与关闭

int main()
{
    //相对路径
    //绝对路径
    ///Users/fan/Documents/c_study/c_test26/data.txt

    //打开文件
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //读文件


    //关闭文件
    fclose(pf);
    pf = NULL;


    return 0;
}

 3. 文件的顺序读写

 3.1 顺序读写函数介绍

 

 

int main()
{
    //相对路径
    //绝对路径
    ///Users/fan/Documents/c_study/c_test26/data.txt

    //打开文件
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","w");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //读文件
    //写文件
    // fputc('a',pf);
    // fputc('b',pf);
    // fputc('c',pf);
    int i = 0;
    for (i = 0; i < 26; i++)
    {
        fputc('a'+i,pf);
    }


    //关闭文件
    fclose(pf);
    pf = NULL;


    return 0;
}
int main()
{
    //相对路径
    //绝对路径
    ///Users/fan/Documents/c_study/c_test26/data.txt

    //打开文件
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //读文件
    int ch = fgetc(pf);
    printf("%c\n",ch);  //a
    ch = fgetc(pf);
    printf("%c\n",ch); //b
    ch = fgetc(pf);
    printf("%c\n",ch); //c
    ch = fgetc(pf);
    printf("%c\n",ch);//d


    //写文件
    // fputc('a',pf);
    // fputc('b',pf);
    // fputc('c',pf);
    // int i = 0;
    // for (i = 0; i < 26; i++)
    // {
    //     fputc('a'+i,pf);
    // }


    //关闭文件
    fclose(pf);
    pf = NULL;


    return 0;
}
int main()
{
    //相对路径
    //绝对路径
    ///Users/fan/Documents/c_study/c_test26/data.txt

    //打开文件
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //读文件
    // int ch = fgetc(pf);
    // printf("%c\n",ch);  //a
    // ch = fgetc(pf);
    // printf("%c\n",ch); //b
    // ch = fgetc(pf);
    // printf("%c\n",ch); //c
    // ch = fgetc(pf);
    // printf("%c\n",ch);//d


    //写文件
    // fputc('a',pf);
    // fputc('b',pf);
    // fputc('c',pf);
    // int i = 0;
    // for (i = 0; i < 26; i++)
    // {
    //     fputc('a'+i,pf);
    // }

    // fputs("hello fan\n",pf);
    // fputs("hello fanfan\n",pf);

    //读文件 - 读一行
    char arr[10] = {0};
    fgets(arr,15,pf);
    printf("%s\n",arr);
    fgets(arr,15,pf);
    printf("%s\n",arr);


    //关闭文件
    fclose(pf);
    pf = NULL;


    return 0;
}
struct S
{
    int a;
    float s;
};

int main()
{
    //相对路径
    //绝对路径
    ///Users/fan/Documents/c_study/c_test26/data.txt

    //打开文件
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //写文件
    //struct S s = {100,3.14f};
    //fprintf(pf,"%d %f",s.a,s.s);
    struct S s = {0};
    fscanf(pf,"%d %f",&(s.a),&(s.s));

    printf("%d %f",s.a,s.s);


    //关闭文件
    fclose(pf);
    pf = NULL;


    return 0;
}
struct S
{
    int a;
    float s;
    char str[10];
};

int main()
{

    struct S s = {99, 6.18f, "bit"};
    //打开文件
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","wb");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }
    //写文件
    fwrite(&s,sizeof(struct S),1,pf);

    //关闭文件
    fclose(pf);
    pf = NULL;

    return 0;
}
int main()
{

    struct S s = {0};
    //打开文件
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","rb");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }
    
    //读文件
    fread(&s,sizeof(struct S),1,pf);
    printf("%d %f %s\n",s.a,s.s,s.str);

    //关闭文件
    fclose(pf);
    pf = NULL;

    return 0;
}

 4. 文件的随机读写

 4.1 fseek

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

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

int main()
{
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //读文件
    //定位文件指针到f
    int ch = fgetc(pf);
    printf("%c\n",ch);   //a

    ch = fgetc(pf);
    printf("%c\n",ch);  //b

    ch = fgetc(pf);
    printf("%c\n",ch);  //c 

    ch = fgetc(pf);
    printf("%c\n",ch);  //d

    fseek(pf,-3,SEEK_END);
    ch = fgetc(pf);
    printf("%c\n",ch);


    //关闭文件
    fclose(pf);
    pf = NULL;



    return 0;
}

4.2 ftell

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

long int ftell ( FILE * stream );

int main()
{
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //读文件
    //定位文件指针到f
    int ch = fgetc(pf);
    printf("%c\n",ch);   //a

    ch = fgetc(pf);
    printf("%c\n",ch);  //b

    ch = fgetc(pf);
    printf("%c\n",ch);  //c 

    ch = fgetc(pf);
    printf("%c\n",ch);  //d

    // fseek(pf,-3,SEEK_END);
    // ch = fgetc(pf);
    // printf("%c\n",ch);
    int pos = ftell(pf);
    printf("%d\n",pos); //4


    //关闭文件
    fclose(pf);
    pf = NULL;



    return 0;
}

4.3 rewind 

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

void rewind ( FILE * stream );

int main()
{
    FILE* pf = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pf == NULL)
    {
        perror("fopen");
        return 1;
    }

    //读文件
    //定位文件指针到f
    int ch = fgetc(pf);
    printf("%c\n",ch);   //a

    ch = fgetc(pf);
    printf("%c\n",ch);  //b

    ch = fgetc(pf);
    printf("%c\n",ch);  //c 

    ch = fgetc(pf);
    printf("%c\n",ch);  //d

    // fseek(pf,-3,SEEK_END);
    // ch = fgetc(pf);
    // printf("%c\n",ch);
    // int pos = ftell(pf);
    // printf("%d\n",pos); //4

    rewind(pf);  //回到起始位置

    ch = fgetc(pf);
    printf("%c\n",ch); //a

    //关闭文件
    fclose(pf);
    pf = NULL;

    return 0;
}

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

6. 文件读取结束的判断  

6.1 被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件的是否结束。

而是应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束。

1. 文本文件读取是否结束,判断返回值是否为EOF (fgetc),或者NULL(fgets)

例如:

fgetc判断是否为EOF.

fgets判断返回值是否为NULL.

2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。

例如:

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

int main(void)
{
    int c; // 注意:int,非char,要求处理EOF
    FILE *fp = fopen("test.txt", "r");
    if (!fp)
    {
        perror("File opening failed");
        return EXIT_FAILURE;
    }
    // fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
    while ((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);
}

//拷贝文件
//拷贝data.txt文件,产生一个新文件data1.txt

int main()
{
    FILE* pfRead = fopen("/Users/fan/Documents/c_study/c_test26/data.txt","r");
    if (pfRead == NULL)
    {
        perror("open file for read");
        return 1;

    }

    FILE* pfWrite = fopen("/Users/fan/Documents/c_study/c_test26/data2.txt","w");
    if (pfWrite == NULL)
    {
        perror("open file for write");
        fclose(pfRead);
        pfRead = NULL;
        return 1;
    }


    //读写文件
    int ch = 0;
    while((ch = fgetc(pfRead)) != EOF)
    {
        fputc(ch,pfWrite);
    }


    //关闭文件
    fclose(pfRead);
    pfRead = NULL;

    fclose(pfWrite);
    pfWrite = NULL;


    return 0;
}

 7. 文件缓冲区

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

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

相关文章

R语言中fread怎么使用?

R语言中 fread 怎么用&#xff1f; 今天分享的笔记内容是数据读取神器fread&#xff0c;速度嘎嘎快。在R语言中&#xff0c;fread函数是data.table包中的一个功能强大的数据读取函数&#xff0c;可以用于快速读取大型数据文件&#xff0c;它比基本的read.table和read.csv函数更…

吴恩达开新课了:面向所有人的生成式 AI 课程!我已偷偷学了起来

作者 | 智商掉了一地 斯坦福大学的吴恩达教授可能是许多人接触 AI 的启蒙课导师吧&#xff0c;在过去的十多年中&#xff0c;他的《Machine Learning》课程已经对数百万的学习者产生了积极影响。 ▲image.png 而随着 ChatGPT 的推出&#xff0c;大模型和各类生成式人工智能&am…

你知道谁是计算机之父吗?

“计算机之父” 这个词通常用来指代计算机科学领域的杰出人物&#xff0c;他们在计算机科学和技术的发展中发挥了重要作用。有多位人物被认为是计算机之父&#xff0c;其中包括&#xff1a; 查尔斯巴贝奇&#xff08;Charles Babbage&#xff09;&#xff1a;是英国的一位杰出的…

Node.js的安装

直接在浏览器中搜索Node.js即可 打开下载好的文件 验证是否安装成功 在cmd中输入 node -v&#xff0c;若结果为版本号那就是成功的 环境配置 配置全局模块所在的路径缓存cache的路径 在安装目录中新建两个文件夹&#xff0c;文件夹名为:node_cache和node_global 输…

STARKs with small finite field:小域带来的迷人性能

1. 引言 前序博客有&#xff1a; 2023年 ZK Hack以及ZK Summit 亮点记为何需关注各ZKP方案的benchmarks&#xff1f; 很久以前&#xff0c;有大量研究和开发致力于改进ZKP性能。研究人员通过采用多种不同的技术&#xff0c;包括但不限于&#xff1a; 不同的IOPs不同的多项式…

【Java 进阶篇】深入了解 Bootstrap 按钮和图标

按钮和图标在网页设计中扮演着重要的角色&#xff0c;它们是用户与网站或应用程序交互的关键元素之一。Bootstrap 是一个流行的前端框架&#xff0c;提供了丰富的按钮样式和图标库&#xff0c;使开发者能够轻松创建吸引人的界面。在本文中&#xff0c;我们将深入探讨 Bootstrap…

c++入门(命名空间, c++输入输出, 缺省参数)

文章目录 1. 命名空间正确的命名定义命名空间的使用 2. c输入与输出标准输入输出对象向流写入 读取数据 3. 缺省参数缺省参数分类缺省参数声明缺省参数初始值 c的简单介绍 C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大…

全波形反演培训的思考与总结

一. InversionNet 最简单的端到端DL_FWI 1. 网络结构&#xff1a; 图1 构建了一个具有编码器-解码器结构的卷积神经网络&#xff0c;根据地震波动数据模拟地下速度结构。编码器主要由卷积层构建&#xff0c;它从输入地震数据中提取高级特征并将其压缩为单个高维向量。解码器然后…

轻量级导出 Excel 标准格式

一般业务系统中都有导出到 Excel 功能&#xff0c;其实质就是把数据库里面一条条记录转换到 Excel 文件上。Java 常用的第三方类库有 Apache POI 和阿里巴巴开源的 EasyExcel 等。另外也有通过 Web 模板技术渲染 Excel 文件导出&#xff0c;这实质是 MVC 模式的延伸&#xff0c…

系列四、FileReader和FileWriter

一、概述 FileReader 和 FileWriter 是字符流&#xff0c;按照字符来操作IO。 1.1、继承体系 二、FileReader常用方法 new FileReader(File/String)# 每次读取单个字符就返回&#xff0c;如果读取到文件末尾返回-1 read()# 批量读取多个字符到数组&#xff0c;返回读取的字节…

【C语言】每日一题(添加逗号)

添加逗号&#xff0c;链接奉上 目录 方法1&#xff1a;整体存入思路&#xff1a;代码实现&#xff1a; 方法2&#xff1a;分段输出思路&#xff1a;代码实现&#xff1a; 方法1&#xff1a;整体存入 思路&#xff1a; 整体思路&#xff1a; 我们发现这个整数N对于最后1位是比…

【Python生活脚本】视频转Gif动图

忘记过去&#xff0c;超越自己 ❤️ 博客主页 单片机菜鸟哥&#xff0c;一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-10-20 ❤️❤️ 本篇更新记录 2023-10-20 ❤️&#x1f389; 欢迎关注 &#x1f50e;点赞 &#x1f44d;收藏 ⭐️留言&#x1f4dd;&#x1f64…

Juniper防火墙SSG-140 session 过高问题

1.SSG-140性能参数 2.问题截图 3.解决方法 &#xff08;1&#xff09;通过telnet 或 consol的方法登录到防火墙&#xff1b; &#xff08;2&#xff09;使用get session 查看总的session会话数&#xff0c;如果大于300 一般属于不正常情况 &#xff08;3&#xff09;使用get…

力扣每日一题48:旋转图像

题目描述&#xff1a; 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],…

任务分配问题(回溯法)

算法设计 问题描述 有n&#xff08;n≥1&#xff09;个任务需要分配给n个人执行&#xff0c;每个任务只能分配给一个人&#xff0c;每个人只能执行一个任务。 第i个人执行第j个任务的成本是c[i][j]&#xff08;1≤i&#xff0c;j≤n&#xff09;。求出总成本最小的分配方案 …

基于Java的人事管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

推荐《中华小当家》

《中华小当家&#xff01;》 [1] 是日本漫画家小川悦司创作的漫画。该作品于1995年至1999年在日本周刊少年Magazine上连载。作品亦改编为同名电视动画&#xff0c;并于1997年发行播出。 时隔20年推出续作《中华小当家&#xff01;极》&#xff0c;于2017年11月17日开始连载。…

简述两种爆破ssh弱口令的方法

SSH 为 Secure Shell 的缩写&#xff0c;由 IETF 的网络小组&#xff08;Network Working Group&#xff09;所制定&#xff1b;SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠&#xff0c;专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止…

【C语言必知必会| 第十篇】指针入门,这一篇就够了

引言 C语言是一门面向过程的、抽象化的通用程序设计语言&#xff0c;广泛应用于底层开发。它在编程语言中具有举足轻重的地位。 此文为【C语言必知必会】系列第十篇&#xff0c;介绍C语言指针&#xff0c;结合专题优质题目&#xff0c;带领读者从0开始&#xff0c;深度掌握知识…