文件操作

参考 https://fishc.com.cn/forum.php?mod=forumdisplay&fid=329&filter=typeid&typeid=583

打开文件

fopen 打开一个文件并返回文件指针。

#include <stdio.h>
...
FILE *fopen(const char *path, const char *mode);

参数解析:

参数 含义
path 该参数是一个 C 语言字符串,指定了待打开的文件路径和文件名(见备注)
mode 1. 该参数是一个 C 语言字符串,指定了文件的打开模式
2. 下面列举了所有可使用的打开模式:
模式 描述
"r" 1. 以只读的模式打开一个文本文件,从文件头开始读取
2. 该文本文件必须存在
"w" 1. 以只写的模式打开一个文本文件,从文件头开始写入
2.如果文件不存在则创建一个新的文件
3. 如果文件已存在则将文件的长度截断为 0(重新写入的内容将覆盖原有的所有内容)
"a" 1. 以追加的模式打开一个文本文件,从文件末尾追加内容
2. 如果文件不存在则创建一个新的文件
"r+" 1. 以读和写的模式打开一个文本文件,从文件头开始读取和写入
2. 该文件必须存在
3. 该模式不会将文件的长度截断为 0(只覆盖重新写入的内容,原有的内容保留)
"w+" 1. 以读和写的模式打开一个文本文件,从文件头开始读取和写入
2. 如果文件不存在则创建一个新的文件
3. 如果文件已存在则将文件的长度截断为 0(重新写入的内容将覆盖原有的所有内容)
"a+" 1. 以读和追加的模式打开一个文本文件
2. 如果文件不存在则创建一个新的文件
3. 读取是从文件头开始,而写入则是在文件末尾追加
"b" 1. 与上面 6 中模式均可结合("rb", "wb", "ab", "r+b", "w+b", "a+b")
2. 其描述的含义一样,只不过操作的对象是二进制文件(见备注)

返回值:

  1. 如果文件打开成功,则返回一个指向 FILE 结构的文件指针;

  2. 如果文件打开失败,则返回 NULL 并设置 errno 为指定的错误。

备注:

  1. path 参数可以是相对路径(../fishc.txt)也可以是绝对路径(/home/FishC/fishc.txt),如果只给出文件名而不包含路径,则表示该文件在当前文件夹中

  2. 从本质上来说,文本文件也是属于二进制文件的,只不过它存放的是相应的字符编码值。

  3. 打开方式要区分文本模式和二进制模式的原因,主要是因为换行符的问题。C 语言用 \n 表示换行符,Unix 系统用 \n,Windows 系统用 \r\n,Mac 系统则用 \r。如果在 Windows 系统上以文本模式打开一个文件,从文件读到的 \r\n 将会自动转换成 \n,而写入文件则将 \n 替换为 \r\n。但如果以二进制模式打开则不会做这样的转换。Unix 系统的换行符跟 C 语言是一致的,所以不管以文本模式打开还是二进制模式打开,结果都是一样的。

关闭文件

fclose 函数用于关闭先前由 fopen 函数打开的文件。

fclose 函数会将缓冲区内的数据写入文件中,并释放系统所提供的文件资源。

#include <stdio.h>
...
int fclose(FILE *fp);

返回值:

  1. 如果文件关闭成功,返回值是 0;

  2. 如果文件关闭失败,返回值是 EOF,并设置 errno 为指定的错误。

写入文件

  1. fputc
  • 函数用于将一个字符写入到指定的文件中并推进文件的位置指示器(用来指示接下来要读写的下一个字符的位置)。
  • fputc 函数和 putc函数两个的功能和描述基本上是一模一样的,它们的区别主要在于实现上:fputc 是一个函数;而 putc 则是一个宏的实现
#include <stdio.h>
...
int fputc(int c, FILE *stream);
  1. fputs
  • fputs 函数用于将一个字符串写入到指定的文件中,表示字符串结尾的 '\0' 不会被一并写入。
#include <stdio.h>
#include <stdlib.h>

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

        if ((fp = fopen("file.txt", "w")) == NULL)
        {
                printf("打开文件失败!\n");
                exit(EXIT_FAILURE);
        }

        fputs("I love FishC.com!\n", fp);

        fclose(fp);

        return 0;
}
  1. fwrite
  • fwrite 函数用于将指定尺寸的数据写入到指定的文件中。
#include <stdio.h>
...
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct Date
{
        int year;
        int month;
        int day;
};

struct Book
{
        char name[40];
        char author[40];
        char publisher[40];
        struct Date date;
};

int main(void)
{
        FILE *fp;
        struct Book *book_for_write, *book_for_read;

        // 为结构体分配堆内存空间
        book_for_write = (struct Book *)malloc(sizeof (struct Book));
        book_for_read = (struct Book *)malloc(sizeof (struct Book));

        if (book_for_write == NULL || book_for_read == NULL)
        {
                printf("内存分配失败!\n");
                exit(EXIT_SUCCESS);
        }

        // 填充结构体数据
        strcpy(book_for_write->name, "《带你学C带你飞》");
        strcpy(book_for_write->author, "小甲鱼");
        strcpy(book_for_write->publisher, "清华大学出版社");
        book_for_write->date.year = 2017;
        book_for_write->date.month = 11;
        book_for_write->date.day = 11;

        if ((fp = fopen("file.txt", "w")) == NULL)
        {
                printf("打开文件失败!\n");
                exit(EXIT_SUCCESS);
        }

        // 将整个结构体写入文件中
        fwrite(book_for_write, sizeof(struct Book), 1, fp);

        // 写入完成,关闭保存文件
        fclose(fp);

        // 重新打开文件,检测是否成功写入数据
        if ((fp = fopen("file.txt", "r")) == NULL)
        {
                printf("打开文件失败!\n");
                exit(EXIT_FAILURE);
        }

        // 在文件中读取结构体并打印到屏幕上
        fread(book_for_read, sizeof(struct Book), 1, fp);

        printf("书名:%s\n", book_for_read->name);
        printf("作者:%s\n", book_for_read->author);
        printf("出版社:%s\n", book_for_read->publisher);
        printf("出版日期:%d-%d-%d\n", book_for_read->date.year, book_for_read->date.month, book_for_read->date.day);

        fclose(fp);

        return 0;
}                           

读取文件

  1. fgetc
  • fgetc 函数用于从文件流中读取下一个字符并推进文件的位置指示器(用来指示接下来要读写的下一个字符的位置)。
  • fgetc 函数和 getc 函数两个的功能和描述基本上是一模一样的,它们的区别主要在于实现上:fgetc 是一个函数;而 getc 则是一个宏的实现
#include <stdio.h>
...
int fgetc(FILE *stream);
  1. fgets
  • fgets 函数用于从指定文件中读取字符串。
  • fgets 函数最多可以读取 size - 1 个字符,因为结尾处会自动添加一个字符串结束符 '\0'。当读取到换行符('\n')或文件结束符(EOF)时,表示结束读取('\n' 会被作为一个合法的字符读取)。
#include <stdio.h>
...
char *fgets(char *s, int size, FILE *stream);
  1. fread
  • fread 函数用于从指定的文件中读取指定尺寸的数据。
#include <stdio.h>
...
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

缓冲区

fflush 函数用于将缓冲区内的数据强制写入指定的文件中。

#include <stdio.h>
...
int fflush(FILE *stream);

返回值:

  1. 如果函数调用成功,返回值是 0;

  2. 如果函数调用失败,返回 EOF 并设置 errno 为指定的错误。

#include <stdio.h>
#include <string.h>

int main(void)
{
        char buff[1024];

        memset(buff, '\0', sizeof(buff));

        // 指定 buff 为缓冲区,_IOFBF 表示当缓冲区已满时才写入 stdout
        setvbuf(stdout, buff, _IOFBF, 1024);

        fprintf(stdout, "This is bbs.fishc.com\n");
        fprintf(stdout, "This output will go into buff\n");

        // fflush强制将上面缓存中的内容写入stdout
        fflush(stdout);

        fprintf(stdout, "this will appear when progream\n");
        fprintf(stdout, "will come after sleeping 5 seconds\n");

        sleep(5);

        return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • 得到当前工作目录,即当前Python脚本工作的目录路径:os.getcwd() 返回指定目录下的所有文件和目录名:...
    Envisage_802b阅读 216评论 0 2
  • 文件基本概念 文件分类文本文件以ASCII码格式存放,一个字节存放一个字符.二进制文件以二进制存储的 文本文件和二...
    低头看云阅读 662评论 0 0
  • 语言中对文件进行操作必须首先打开文件,打开文件主要涉及到fopen函数。fopen函数的原型为 FILE* fop...
    朱森阅读 800评论 0 1
  • 第十三章 文件 一,C文件概述 从用户的角度看,文件可分为 普通文件 和 设备文件 ;设备文件 为 显示器、打印机...
    坚持到底v2阅读 867评论 0 2
  • 第十章 文件操作 10.1 概述 10.1.1 磁盘文件和设备文件 1.磁盘文件指一组相关数据的有序集合,通常存储...
    CodeDove阅读 639评论 0 1