首页 > 其他分享 >c语言文件操作

c语言文件操作

时间:2024-09-10 18:53:37浏览次数:11  
标签:fp 文件 读取 函数 FILE 操作 指针 语言

   

目录

1、文件操作概述

2、文件的打开与关闭

3、文件的顺序读取与写入

3.1 fputs、fgets函数

3.2  fscanf、fprintf 函数

4、文件的随机读取与写入

4.1 fseek函数

4.2 ftell函数 

 4.3 rewind 函数

5、文件读取结束的判定 


1、文件操作概述

       每个被使⽤的文件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,文件状态及⽂件当前的位置等)。这些信息是保存在⼀个结构体变量中的。该结构体类型是由系统声明的,取名FILE。每当打开⼀个⽂件的时候,系统会根据⽂件的情况⾃动创建⼀个FILE结构的变量,并填充其中的信息,使⽤者不必关心细节。

       ⼀般通过⼀个FILE的指针来维护这个FILE结构的变量,这样使⽤起来更加⽅便,定义如下:

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

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

 

2、文件的打开与关闭

       文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
       在编写程序的时候,在打开文件的同时,都会返回⼀个 FILE* 的指针变量指向该文件,也相当于建立了指针和文件的关系。fopen 函数来打开⽂件, fclose 函数来关闭⽂件。

FILE *fopen(const char *filename, const char *mode);
int fclose ( FILE * stream );

       其中 fileame 是要打开的文件名;mode表示文件的打开模式,如下:

⽂件使⽤⽅式     含义        如果指定⽂件不存在
“r”(只读)  为了输⼊数据,打开⼀个已经存在的⽂本⽂件    出错
“w”(只写)为了输出数据,打开⼀个⽂本⽂件建⽴⼀个新的⽂件
“a”(追加)向⽂本⽂件尾添加数据建⽴⼀个新的⽂件
“rb”(只读)为了输⼊数据,打开⼀个⼆进制⽂件出错
“wb”(只写)为了输出数据,打开⼀个⼆进制⽂件建⽴⼀个新的⽂件
“ab”(追加)向⼀个⼆进制⽂件尾添加数据建⽴⼀个新的⽂件
“r+”(读写)为了读和写,打开⼀个⽂本⽂件出错
“w+”(读写)为了读和写,建议⼀个新的⽂件建⽴⼀个新的⽂件
“a+”(读写)打开⼀个⽂件,在⽂件尾进⾏读写建⽴⼀个新的⽂件
“rb+”(读写)为了读和写打开⼀个⼆进制⽂件出错
“wb+”(读写)为了读和写,新建⼀个新的⼆进制⽂件建⽴⼀个新的⽂件
“ab+”(读写)打开⼀个⼆进制⽂件,在⽂件尾进⾏读和写建⽴⼀个新的⽂件

实例代码如下:

#include <stdio.h>  
  
int main() {  
    FILE *fp; // 声明一个文件指针  
    fp = fopen("C:\\Users\\dell\\Desktop\\example.txt", "r"); // 打开文件,并将返回的文件指针赋值给fp  
    if (fp == NULL) {  
        perror("Error opening file");  
        return -1;  
    }  
    // ... 文件操作代码 ...  
    fclose(fp); // 关闭文件,并释放文件指针  
    return 0;  
}

3、文件的顺序读取与写入

函数名功能适⽤于
fgetc字符输⼊函数所有输⼊流
fputc字符输出函数所有输出流
fgets⽂本⾏输⼊函数所有输⼊流
fputs⽂本⾏输出函数所有输出流
fscanf格式化输⼊函数所有输⼊流
fprintf格式化输出函数所有输出流
fread⼆进制输⼊⽂件
fwrite⼆进制输出⽂件

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

3.1 fputs、fgets函数

       fputs 函数是一个用于向文件写入字符串的标准库函数。将指定的字符串(不包括空字符 '\0')写入到指定的输出流中(一般为文件)。如果成功,fputs 函数返回非负值;如果发生错误,则返回 EOF(通常定义为 -1)。

int fputs(const char *s, FILE *stream);
  • s 是指向以空字符 '\0' 结尾的字符串的指针。注意,fputs 不会写入字符串的终止空字符。
  • stream 是指向 FILE 对象的指针,该对象标识了要写入的输出流。在文件操作中,这通常是一个通过 fopen 函数打开的文件指针。

        fgets函数用于从指定的文件流中读取一行数据,并存储到字符串中。这个函数会读取直到遇到换行符(\n)、文件结束符(EOF)或已经读取了指定数量的字符(不包括最后的空字符 \0,该函数会自动在字符串末尾添加这个空字符以标记字符串的结束)为止的字符。如果成功会返回指向 str 的指针;如果到达文件末尾(EOF)或发生错误,它会返回 NULL。但是,请注意,如果读取的最后一行没有换行符,并且读取的字符数小于 n-1,则 fgets 仍会成功返回,并且字符串会以空字符 \0 结尾,但不会自动添加换行符。

char *fgets(char *str, int n, FILE *stream);
  • str 是一个指向字符数组的指针,用于存储读取的字符串。
  • n 是要读取的最大字符数(包括最后的空字符 \0)。因此,实际上最多可以读取 n-1 个字符加上一个空字符 \0
  • stream 是一个指向 FILE 对象的指针,该对象标识了要从中读取数据的输入流。

 代码示例如下:

#define _CRT_SECURE_NO_WARNINGS  
#include <stdio.h>  
  
int main() {  
    FILE *fp;  
  
    // 打开文件以写入  
    fp = fopen("C:\\Users\\dell\\Desktop\\example.txt", "w");  
    if (fp == NULL) {  
        perror("Error opening file");  
        return(-1);  
    }  
  
    // 写入数据  
    fputs(fp, "Hello, World!\n");  
  
    // 关闭文件  
    fclose(fp);  
  
    // 重新打开文件以读取  
    fp = fopen("C:\\Users\\dell\\Desktop\\example.txt", "r");  
    if (fp == NULL) {  
        perror("Error opening file");  
        return(-1);  
    }  
  
    // 读取数据  
    char buff[255];  
    if (fgets(buff, 255, fp) != NULL)  
        printf("%s", buff);  
  
    // 关闭文件  
    fclose(fp);  
  
    return 0;  
}
3.2  fscanf、fprintf 函数

   fscanf 函数用于从指定的文件流中读取数据,并根据提供的格式字符串解析这些数据,其返回值为成功读取的项目数,如果到达文件末尾或发生读取错误,则可能返回 EOF。

int fscanf(FILE *stream, const char *format, ...);
  • stream 是指向 FILE 对象的指针,该对象标识了要从中读取数据的文件流。
  • format 是格式字符串,指定了后续参数的类型和如何从输入中解析它们。
  • ... 表示可变数量的附加参数,这些参数指向用于存储从文件中读取的数据的变量。

   fprintf 函数用于向指定的文件流写入数据,其工作方式类似于 printf,但它是向文件写入而不是标准输出。 其返回值为成功写入的字符数(不包括末尾的空字符),如果发生错误,则返回负值。

int fprintf(FILE *stream, const char *format, ...);
  • stream 是指向 FILE 对象的指针,该对象标识了要写入数据的文件流。
  • format 是格式字符串,指定了后续参数如何被格式化为字符串并写入文件。
  • ... 表示可变数量的附加参数,这些参数是要写入文件的数据。

 代码示例如下: 

#include <stdio.h>  
  
int main() {  
    FILE *inputFile = fopen("C:\\Users\\dell\\Desktop\\example.txt", "r");  
    if (inputFile == NULL) {  
        perror("Error opening input file");  
        return -1;  
    }  
  
    FILE *outputFile = fopen("C:\\Users\\dell\\Desktop\\output.txt", "w");  
    if (outputFile == NULL) {  
        fclose(inputFile); // 不要忘记关闭已打开的文件  
        perror("Error opening output file");  
        return -1;  
    }  
  
    int age;  
    float height;  
    char name[50]; // 假设名字不会超过49个字符加上一个空字符  
  
    // 从输入文件读取数据  
    while (fscanf(inputFile, "%s %d %f", name, &age, &height) == 3) {  
        // 处理数据(在这个例子中我们只是简单地回显)  
  
        // 将处理后的数据(或原样)写入输出文件  
        fprintf(outputFile, "Name: %s, Age: %d, Height: %.2f\n", name, age, height);  
    }  
  
    // 关闭文件  
    fclose(inputFile);  
    fclose(outputFile);  
  
    return 0;  
}

        注:这个例子中使用了%s来读取字符串(即名字)。然而,使用%sfscanf一起读取字符串时应当格外小心,因为它不会检查目标缓冲区的边界,可能会导致缓冲区溢出。在实际应用中,你可能想要使用fgetssscanf(或适当的字符串处理函数)的组合来更安全地读取字符串。

        此外,假设input.txt文件包含以下格式的数据:

John 30 1.75  
Jane 25 1.65  
Doe 40 1.80

         执行上述程序后,output.txt文件将包含相同的数据,但每行前面都添加了"Name: ", "Age: ", 和 "Height: "的标记,并且数据项之间以逗号分隔。

4、文件的随机读取与写入

       文件指针的偏移(offset)是指文件指针当前位置与文件开头之间的字节数。通过改变文件指针的偏移量,可以实现对文件的随机访问。

4.1 fseek函数

       fseek 函数根据文件指针的位置和偏移量来定位文件指针,如果 fseek 函数成功执行,它会返回 0。如果发生错误(例如,指定的位置超出了文件的实际大小,或者底层系统不支持文件定位操作),它会返回非零值,并设置 errno 以指示错误类型。

int fseek(FILE *stream, long offset, int whence);
  • stream 是指向 FILE 对象的指针,该对象标识了要操作的文件。
  • offset 是相对于 whence 指定的位置的偏移量,以字节为单位。偏移量可以是正数或负数。
  • whence 是一个整数,指定了 offset 的起始位置。它必须是以下三个常量之一:
    • SEEK_SET:文件的开头。
    • SEEK_CUR:文件指针的当前位置。
    • SEEK_END:文件的末尾。

       以下是一个使用 fseek 函数的示例,该示例将文件指针移动到文件的开头,然后向前移动一定字节数,并读取该位置之后的数据:   

#include <stdio.h>  
#include <stdlib.h>  
  
int main() {  
    FILE *fp = fopen("example.txt", "r");  
    if (fp == NULL) {  
        perror("Error opening file");  
        return EXIT_FAILURE;  
    }  
  
    // 将文件指针移动到文件的开头  
    if (fseek(fp, 0, SEEK_SET) != 0) {  
        perror("Error seeking to the beginning of the file");  
        fclose(fp);  
        return EXIT_FAILURE;  
    }  
  
    // 假设我们要跳过前10个字节  
    if (fseek(fp, 10, SEEK_SET) != 0) {  
        perror("Error seeking to 10 bytes from the beginning of the file");  
        fclose(fp);  
        return EXIT_FAILURE;  
    }  
  
    // 从当前位置开始读取数据  
    char buffer[100];  
    if (fgets(buffer, sizeof(buffer), fp) != NULL) {  
        // 处理读取的数据...  
        printf("%s", buffer);  
    }  
  
    // 关闭文件  
    fclose(fp);  
  
    return EXIT_SUCCESS;  
}
4.2 ftell函数 

ftell函数用于获取文件指针的当前位置,即相对于文件开头的偏移量(以字节为单位)。

#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); // non-portable
        size = ftell(pFile);
        fclose(pFile);
        printf("Size of myfile.txt: %ld bytes.\n", size);
    }
    return 0;
}
 4.3 rewind 函数

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

#include <stdio.h>  
  
int main() {  
    FILE *fp;  
    char buffer[100];  
  
    // 打开文件  
    fp = fopen("example.txt", "r");  
    if (fp == NULL) {  
        perror("Error opening file");  
        return(-1);  
    }  
  
    // 第一次读取文件  
    if (fgets(buffer, 100, fp) != NULL) {  
        printf("First time reading: %s", buffer);  
    }  
  
    // 使用 rewind 重置文件位置指示器  
    rewind(fp);  
  
    // 第二次读取文件(从头开始)  
    if (fgets(buffer, 100, fp) != NULL) {  
        printf("Second time reading: %s", buffer);  
    }  
  
    // 关闭文件  
    fclose(fp);  
  
    return 0;  
}

注意事项:

  • 使用 rewind 函数之前确保文件已经成功打开,并且是以读取模式(如 "r" 或 "r+")打开的。
  • 如果文件是以写入模式("w" 或 "w+")打开的,并且文件已经存在,那么 rewind 函数会将位置指示器重置到文件的开头,但此时文件的内容可能已经被清空(取决于具体的实现和文件模式)。
  • 在使用完文件后,记得使用 fclose 函数关闭文件,以释放相关资源。

 

5、文件读取结束的判定 

       在文件读取过程中,不能⽤ feof 函数的返回值直接来判断⽂件的是否结束。 feof 的作用是:当文件读取结束的时候,判断读取结束的原因是否是:遇到文件尾结束。

1. ⽂本⽂件读取是否结束,判断返回值是否为 EOF ( fgetc ),或者 NULL ( fgets )
例如:
• fgetc 判断是否为 EOF .
• fgets 判断返回值是否为 NULL .
2. ⼆进制⽂件的读取结束判断,判断返回值是否⼩于实际要读的个数。

#include <stdio.h>
#include <stdlib.h>
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);
}

标签:fp,文件,读取,函数,FILE,操作,指针,语言
From: https://blog.csdn.net/2301_81723939/article/details/142026240

相关文章

  • 一些程序设计语言
            ......
  • FatFs文件系统的移植---(STM32标准库)
    官网最新版本:http://elm-chan.org/fsw/ff/00index_e.html一、下载最新版本FATFA文件系统在这里不多做介绍了,只展示移植过程和使用方法(结尾有修改好的代码)二、移植代码1.解压文件压缩包里面有两个文件:documents是一些帮助文档,不需要管;source里面是源码,把里面全部的文件复......
  • 磁盘映射(C语言)
            目录一、背景介绍二、磁盘映射技术概述  1.磁盘映射原理  2.磁盘映射的优势三、C语言实现磁盘映射        磁盘映射技术在C语言中的应用能够极大地提高文件操作的效率。本文将详细介绍磁盘映射的概念、如何在C语言中实现磁盘映射,并通过......
  • 有关如何在不使用 iTunes 的情况下在 PC 上访问 iPhone 文件的完整指南
    想要从PC查看或研究iPhone上的文件吗?或者您需要将文件从iPhone传输到PC进行备份?虽然苹果提供了iTunes供用户访问或传输iOS数据,但不使用iTunes的原因有很多:过时的用户界面、频繁崩溃、传输速度慢等。如果您想知道如何在没有iTunes的情况下在PC上访问iPhone......
  • pandas读取xlsx文件使用sqlachemy写到数据库
    pandas读取xlsx文件使用sqlachemy写到数据库要使用pandas和SQLAlchemy将Excel文件中的数据读取到数据库中,你可以按照以下步骤进行操作:安装必要的库:确保你已经安装了pandas、SQLAlchemy和openpyxl(用于读取Excel文件)。可以使用以下命令安装:pipinstallpandas......
  • Python存储与读写二进制文件
    技术背景一般情况下我们会选择使用明文形式来存储数据,如json、txt、csv等等。如果是需要压缩率较高的存储格式,还可以选择使用hdf5或者npz等格式。还有一种比较紧凑的数据存储格式,就是直接按照二进制格式存储。这种格式下,存储的数据之间没有间隔符,在没有压缩的情况下应该是......
  • vue 可选链操作符(?.)报错
    一直用的好好的这个运算符,换了个项目,用不了了首先交代一下,vue版本是2.6.11,node版本是v14.17.4,vue-template-compiler也是2.6.11首先哈,我们升级一下vue到2.7.xx版本[email protected]@2.7.0然后安装这个插件npminstall'@babel/plugin-proposal-opti......
  • 搭建企业内部的大语言模型系统
    大纲开源大语言模型大语言模型管理私有大语言模型服务部署方案开源大语言模型担心安全与隐私?可私有部署的开源大模型商业大模型,不支持私有部署ChatGPTClaudeGoogleGemini百度问心一言开源大模型,支持私有部署MistralMetaLlamaChatGLM阿里通义千问常用开源大模型列表开源大模型分支......
  • DeAdmin 不仅仅是可以一键完成crud操作的后台管理系统
    在后台管理系统中,crud是常见的需求,即使每次都是cv操作都是一个不小的工作量。在DeAdmin中内置了一键操作的功能,完成后修改部分模型属性,再调整下列表及表单的展示信息即可快速完成。功能介绍后端1.首先会创建文章和分类的模型记录,包含了文字模块的常用字段信息2.分别创建......
  • java上传文件接口开发uploadFile
    controller层:@PostMapping("/uploadFile")publicServiceResultuploadFile(MultipartFilefile,@RequestParamStringcompareType){returnprimaryService.uploadFile(file,compareType);}service层:/***样本文件上传*@p......