C语言:文件读写

这是很基础的教程,我只是写给自己看,作为一个学习笔记记录一下,如果正在阅读的你觉得简单,请不要批评,可以关掉选择离开

如何学好一门编程语言

  • 掌握基础知识,为将来进一步学习打下良好的基础。
  • 上机实践,通过大量的例题学习怎么设计算法,培养解题思路。
  • 养成良好的编码习惯,注释一定要写,要不然保你一周后自己写的代码都不认识了

  这篇博客将介绍 C 程序 如何打开、关闭、读取和写入文本文件或二进制文件。一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节

打开文件

  C语言中,使用 fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,该函数返回 FILE类型文件指针。

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

参数

  • filename:文件名(字符串)
  • mode:模式,如下表
模式描述
r 以读模式打开文件
w

以写模式打开文件

  • 如果文件存在,则会重新写入。
  • 如果文件不存在,则会创建一个新文件,并从头写入内容。
a

打开一个文本文件,以追加模式写入文件(在已有的文件内容中追加内容)

  • 如果文件不存在,则会创建一个新文件。
r+ 打开一个文本文件,允许读写文件。
w+

打开一个文本文件,允许读写文件。

  • 如果文件已存在,则文件会重新写入。
  • 如果文件不存在,则会创建一个新文件。从文件的开头写入内容。
a+

打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。

  • 读取会从文件的开头开始
  • 写入则只能是追加模式

如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式:

"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"

做一个有高修养的程序员,当我们打开文件夹时,最好做一下判断,是否打开成功

FILE *f;
f = fopen("../file","rb");
if (f==NULL){
  printf("!Error: Cant't open file.\n");
  exit(1);    // 终止程序
}

 

 

关闭文件

  关闭文件使用 fclose( ) 函数

int fclose( FILE *fp );

关闭成功,fclose( ) 函数返回零,关闭文件时发生错误,函数返回 EOF

关闭后会清空缓冲区中的数据,并释放用于该文件的所有内存。所以应该养成打开文件记得关闭的习惯。

文本 I/O 读&写

fgetc() & fputc()

int fgetc(FILE *stream)

参数stream:指向FILE对象的指针

返回:从 fp 所指向的输入文件中读取一个字符。返回值是读取的字符,如果发生错误则返回 EOF。

#include <stdio.h>

int main() {
    FILE *fp;
    int c;
    int n = 0;

    fp = fopen("file.txt", "r");
    if (fp == NULL) {
        perror("打开文件时发生错误");
        return (-1);
    }
    do {
        c = fgetc(fp);
        if (feof(fp)) {
            break;
        }
        printf("%c", c);    // We are in 2014
    } while (1);

    fclose(fp);
    return (0);
}
View Code

int fputc(int char, FILE *stream)

把字符 char (ASCII值)写入到 文件流 中,并把位置标识符往前移动。

返回:如果写入成功,返回被写入的ASCII码对应的字符。如果发生错误,则返回 EOF,并设置错误标识符。

#include <stdio.h>

int main() {
    FILE *fp;
    int ch;

    fp = fopen("../file.txt", "w+");
    for (ch = 33; ch <= 100; ch++) {
        fputc(ch, fp);
    }
    fclose(fp);

    return 0;
}
// file.txt文件
// !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcd
View Code

fgets() & fputs()

int fgetc(FILE *stream)

参数:stream:指向FILE对象的指针

返回:从 fp 所指向的输入文件中读取一个字符。返回值是读取的字符,如果发生错误则返回 EOF。

#include <stdio.h>

int main() {
    FILE *fp;
    int c;
    int n = 0;

    fp = fopen("file.txt", "r");
    if (fp == NULL) {
        perror("打开文件时发生错误");
        return (-1);
    }
    do {
        c = fgetc(fp);
        if (feof(fp)) {
            break;
        }
        printf("%c", c);    // We are in 2014
    } while (1);

    fclose(fp);
    return (0);
}
View Code

int fputs(const char *str, FILE *stream)

把字符串str 写入到文件流 stream 中,但不包括空字符。

返回:如果写入成功,它会返回一个非负值,如果发生错误,则会返回 EOF

#include <stdio.h>

int main() {
    FILE *fp;

    fp = fopen("../file.txt", "w+");

    fputs("这是 C 语言。", fp);
    fputs("这是一种系统程序设计语言。", fp);

    fclose(fp);

    return (0);
}
//file.txt内容
//这是 C 语言。这是一种系统程序设计语言。
View Code

fscanf() & fprintf()

int fscanf(FILE *stream, const char *format, ...)

从文件流中读取格式化输入,但是在遇到第一个空格和换行符时,它会停止读取。

参数:

  • stream:这是指向 FILE 对象的指针,该 FILE 对象标识了流。
  • format:这是 C 字符串,
#include <stdio.h>
#include <stdlib.h>


int main() {
    char str1[10], str2[10], str3[10];
    int year;
    FILE *fp;

    fp = fopen("file.txt", "w+");
    fputs("We are in 2014", fp);

    rewind(fp);
    fscanf(fp, "%s %s %s %d", str1, str2, str3, &year);

    printf("Read String1 |%s|\n", str1);
    printf("Read String2 |%s|\n", str2);
    printf("Read String3 |%s|\n", str3);
    printf("Read Integer |%d|\n", year);

    fclose(fp);

    return (0);
}
//Read String1 |We|
//Read String2 |are|
//Read String3 |in|
//Read Integer |2014|
View Code

int fprintf(FILE *stream, const char *format, ...)

发送格式化输出到文件流中

参数

  • stream:文件流
  • format:这是 C 字符串,包含了要被写入到流 stream 中的文本。
#include <stdio.h>

int main() {
    FILE *fp;

    fp = fopen("../file.txt", "w+");
    fprintf(fp, "%s %s %s %d", "We", "are", "in", 2021);

    fclose(fp);

    return (0);
}
//file.txt内容
//We are in 2021
View Code

二进制 I/O 函数

二进制写

size_t fwrite ( void * ptr, size_t size, size_t count, FILE *stream);

把 指针ptr 所指向的地址中的数据写入到给定文件流中。

参数

  • ptr:指向要被写入的元素的指针。数组就是数组名,结构体要在结构体前面加个&
  • size:要被写入的每个元素的大小,以字节为单位。
  • count:元素的个数
  • stream:文件流

返回:写入成功,返回写入元素的总数(size_t类型)

#include <stdio.h>

int main() {
    FILE *f;
//    char str[] = "never blog";
    struct Student {
        int num;
        int age;
    } stud = {1, 2};

    f = fopen("../R_and_A/test.txt", "wb");

//    fwrite(str, sizeof(stud), 1, f);      // 写入数组
    fwrite(&stud, sizeof(stud), 1, f);        // 写入接结构体
    fclose(f);

    return 0;
}

二进制读

size_t fread ( void *ptr, size_t size, size_t count, FILE *stream );

从文件流 stream 读取数据到 ptr 所指向的地址中。

参数

  • ptr:读取到的数据 要存放的地址
  • size:要读取的每个元素的大小,以字节为单位。
  • count:元素的个数,每个元素的大小为 size 字节。
  • stream:FILE 对象的指针

返回:读取成功返回count (size_t类型),读取失败返回 -1。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。

#include <stdio.h>

int main() {
    FILE *fp;
//    char str[20];
    struct Student {
        int num;
        int age;
    } stud;

    fp = fopen("../R_and_A/test.txt", "rb");

//    fread(str, sizeof(str), 1, fp);   // 读取数组
    fread(&stud, sizeof(stud), 1, fp);

    printf("stud.num:%d,stud.age:%d", stud.num, stud.age);
    // stud.num:1,stud.age:2
    fclose(fp);

    return 0;
}

文件流的锚操作

锚可以理解为我们打字时候这个一闪一闪的光标。

设置文件流的 锚的位置为文件开头: void rewind(FILE *stream) 

int fseek(FILE *stream, long int offset, int whence)

设置文件流 的偏移 offset

  • stream:指向 FILE 对象的指针
  • offset:偏移量,以字节为单位
  • whence:文件指针的位置
    • SEEK_SET:文件开头
    • SEEK_CUR:文件指针的当前位置
    • SEEK_END:文件的末尾

返回:如果成功,则该函数返回零,否则返回非零值。

int feof(FILE *stream)

测试时候读取到文件末尾,返回一个非零值,否则返回零。

FILE *fp;
char buf[512];

fp = fopen("file.txt", "rb");
if(feof(fp)){
    fread (buf, sizeof(char), sizeof(buf), fv);
}

int ferror(FILE *stream)

测试文件是否读取成功,当读写出现错误时返回一个非零值,否则返回0。

FILE *fp;
fp = fopen("file.txt", "w");
if(ferror(fp)){
  printf("读取文件:file.txt 时发生错误\n");
}

 

参考

菜鸟教程

posted @ 2021-07-14 18:25  凌逆战  阅读(108)  评论(0编辑  收藏  举报