让你提前认识软件开发(18):C语言中常用的文件操作函数总结及使用方法演示代码

第1部分 重新认识C语言

C语言中常用的文件操作函数总结及使用方法演示代码

 

        在C语言中,有关文件操作的函数多达数十种,但并非每个函数都经常会被用到。
        本文对实际软件开发项目中常用的C文件操作函数的用法进行了总结,并用实际的C代码来演示了它们的用法。

 

1. C语言中常用的文件操作函数总结

(1) fopen

作用:打开文件。

表头文件:#include <stdio.h>

定义函数:FILE *fopen(const char *path, const char *mode);

函数说明:参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。

mode有下列几种形态字符串:

r:打开只读文件,该文件必须存在。

r+:打开可读写的文件,该文件必须存在。

w:打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。

w+:打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a:以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。

a+:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。

上述的形态字符串都可以再加一个b字符,如rb、w+b或ab+等组合,加入b字符用来告诉函数库打开的文件为二进制文件,而非纯文字文件。不过在POSIX系统,包含Linux都会忽略该字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask值。

返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败,则返回NULL,并把错误代码存在errno中。

附加说明:一般而言,打开文件后会作一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。

 

(2) fclose

作用:关闭文件

表头文件:#include <stdio.h>

定义函数:int fclose(FILE *stream);

函数说明:fclose()用来关闭先前fopen()打开的文件。此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。

返回值:若关闭文件动作成功则返回0,有错误发生时则返回EOF并把错误代码存到errno中。

错误代码:EBADF表示参数stream非已打开的文件。

 

(3) fgetc

作用:由文件中读取一个字符。

表头文件:include <stdio.h>

定义函数:int fgetc(FILE *stream);

函数说明:fgetc()从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时便返回EOF。

返回值:getc()会返回读取到的字符,若返回EOF则表示到了文件尾。

 

(4) fgets

作用:由文件中读取一字符串。

表头文件:include<stdio.h>

定义函数:char *fgets(char *s, int size, FILE *stream);

函数说明:fgets()用来从参数stream所指的文件内读入字符并存到参数s所指的内存空间,直到出现换行字符、读到文件尾或是已读了size-1个字符为止,最后会加上NULL作为字符串结束。

返回值:fgets()若成功则返回s指针,返回NULL则表示有错误发生。

 

(5) fflush

作用:更新缓冲区。

表头文件:#include <stdio.h>

定义函数:int fflush(FILE *stream);

函数说明:fflush()会强迫将缓冲区内的数据写回参数stream指定的文件中。如果参数stream为NULL,fflush()会将所有打开的文件数据更新。

返回值:成功返回0,失败返回EOF,错误代码存于errno中。

错误代码:EBADF参数stream指定的文件未被打开,或打开状态为只读。

 

(6) fputc

作用:将一指定字符写入文件流中。

表头文件:#include <stdio.h>

定义函数:int fputc(int c, FILE *stream);

函数说明:fputc会将参数c转为unsigned char后写入参数stream指定的文件中。

返回值:fputc()会返回写入成功的字符,即参数c。若返回EOF,则代表写入失败。

 

(7) fputs

作用:将一指定的字符串写入文件内。

表头文件:#include <stdio.h>

定义函数:int fputs(const char *s, FILE *stream);

函数说明:fputs()用来将参数s所指的字符串写入到参数stream所指的文件内。

返回值:若成功,则返回写入的字符个数,返回EOF则表示有错误发生。

 

(8) fread

作用:从文件流读取数据。

表头文件:#include <stdio.h>

定义函数:size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

函数说明:fread()用来从文件流中读取数据。参数stream为已打开的文件指针,参数ptr指向欲存放读取进来的数据空间,读取的字符数以参数size*nmemb来决定。fread()会返回实际读取到的nmemb数目,如果此值比参数nmemb来得小,则代表可能读到了文件尾或有错误发生,这时必须用feof()或ferror()来决定发生了什么情况。

返回值:返回实际读取到的nmemb数目。

 

(9) fseek

作用:移动文件流的读写位置。

表头文件:#include <stdio.h>

定义函数:int fseek(FILE *stream, long offset, int whence);

函数说明:fseek()用来移动文件流的读写位置。参数stream为已打开的文件指针,参数offset为根据参数whence来移动读写位置的位移数。

参数whence为下列其中一种:

SEEK_SET:从距文件开头offset位移量为新的读写位置,SEEK_CUR以目前的读写位置往后增加offset个位移量,SEEK_END将读写位置指向文件尾后再增加offset个位移量。

当whence值为SEEK_CUR 或SEEK_END时,参数offset允许负值的出现。

下列是较特别的使用方式:

1) 欲将读写位置移动到文件头时:fseek(FILE *stream, 0, SEEK_SET);

2) 欲将读写位置移动到文件尾时:fseek(FILE *stream, 0, SEEK_END);

返回值:当调用成功时,则返回0,若有错误,则返回-1,errno会存放错误代码。

附加说明:fseek()不像lseek()会返回读写位置,因此必须使用ftell()来取得目前读写的位置。

 

(10) ftell

作用:取得文件流的读取位置。

表头文件:#include <stdio.h>

定义函数:long ftell(FILE * stream);

函数说明:ftell()用来取得文件流目前的读写位置,参数stream为已打开的文件指针。

返回值:当调用成功时则返回目前的读写位置,若有错误则返回-1,errno会存放错误代码。

错误代码:EBADF 参数stream无效或可移动读写位置的文件流。

 

(11) fwrite

作用:将数据写至文件流。

表头文件:#include <stdio.h>

定义函数:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

函数说明:fwrite()用来将数据写入文件流中。参数stream为已打开的文件指针,参数ptr指向欲写入的数据地址,总共写入的字符数以参数size*nmemb来决定。fwrite()会返回实际写入的nmemb数目。

返回值:返回实际写入的nmemb数目。

 

(12) getc

作用:由文件中读取一个字符。

表头文件:#include <stdio.h>

定义函数:int getc(FILE *stream);

函数说明:getc()用来从参数stream所指的文件中读取一个字符。若读到文件尾而无数据时,便返回EOF。虽然getc()与fgetc()作用相同,但getc()为宏定义,非真正的函数调用。

返回值:getc()会返回读取到的字符,若返回EOF则表示到了文件尾。

 

(13) getchar

作用:由标准输入设备内读进一字符。

表头文件:#include <stdio.h>

定义函数:int getchar(void);

函数说明:getchar()用来从标准输入设备中读取一个字符,然后将该字符从unsigned char转换成int后返回。

返回值:getchar()会返回读取到的字符,若返回EOF则表示有错误发生。

附加说明:getchar()非真正函数,而是getc(stdin)宏定义。

 

(14) gets

作用:由标准输入设备内读进一字符串。

表头文件:#include <stdio.h>

定义函数:char *gets(char *s);

函数说明:gets()用来从标准设备读入字符并存到参数s所指的内存空间,直到出现换行字符或读到文件尾为止,最后加上NULL作为字符串结束。

返回值:gets()若成功则返回s指针,返回NULL则表示有错误发生。

附加说明:由于gets()无法知道字符串s的大小,必须遇到换行字符或文件尾才会结束输入,因此容易造成缓冲溢出的安全性问题。建议使用fgets()取代。

 

(15) putc

作用:将一指定字符写入文件中。

表头文件:#include <stdio.h>

定义函数:int putc(int c, FILE *stream);

函数说明:putc()会将参数c转为unsigned char后写入参数stream指定的文件中。虽然putc()与fputc()作用相同,但putc()为宏定义,非真正的函数调用。

返回值:putc()会返回写入成功的字符,即参数c。若返回EOF则代表写入失败。

 

(16) putchar

作用:将指定的字符写到标准输出设备。

表头文件:#include <stdio.h>

定义函数:int putchar(int c);

函数说明:putchar()用来将参数c字符写到标准输出设备。

返回值:putchar()会返回输出成功的字符,即参数c。若返回EOF,则代表输出失败。

附加说明:putchar()非真正函数,而是putc(c, stdout)宏定义。

 

(17) feof

作用:检查文件流是否读到了文件尾。

表头文件:#include <stdio.h>

定义函数:int feof(FILE * stream);

函数说明:feof()用来侦测是否读取到了文件尾,尾数stream为fopen()所返回之文件指针。如果已到文件尾,则返回非零值,其他情况返回0。

返回值:返回非零值代表已到达文件尾。

 

(18) clearer

作用:清除文件流的错误旗标。

表头文件:#include <stdio.h>

定义函数:void clearerr(FILE *stream);

函数说明:clearerr()清除参数stream指定的文件流所使用的错误旗标。

返回值:无。

 

2. C语言中常用的文件操作函数的使用方法演示

       假设在当前工程目录下有一个有具体内容的文件Example.txt,则利用文件操作函数对其进行各种操作的演示如下代码所示(注意:如果要测试某一个或几个函数,只需要提取其中的部分代码即可):

/**********************************************************************

*版权所有 (C)2014, Zhou Zhaoxiong。

*

*文件名称: TestFileOperation.c

*文件标识:无

*内容摘要:对C语言中常用的文件操作函数进行测试

*其它说明:无

*当前版本: V1.0

*作   者: Zhou Zhaoxiong

*完成日期: 20140503

*

*修改记录1://修改历史记录,包括修改日期、版本号、修改人及修改内容

*修改日期: 20140503

*版本号: V1.0

*修改人: Zhou Zhaoxiong

*修改内容:创建

**********************************************************************/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

// 数据类型

typedef unsigned char       UINT8;

typedef unsigned int        UINT32;

 

 

/**********************************************************************

*功能描述:主函数

*输入参数:无

*输出参数:无

*返回值:0-执行成功  1-执行失败

*其它说明:无

*修改日期         版本号    修改人           修改内容

* ----------------------------------------------------------------------------------------------

*20140503        V1.0     Zhou Zhaoxiong       创建

***********************************************************************/

UINT32 main(void)

{

    FILE  *fp                                    = NULL;

    UINT8 cSingleChar                 = '\0';

    UINT8 szString[100]               = {0};

    UINT32 iFileDescription      = 0;

    UINT8  szAlphabeticSet[30]  = {0};

    UINT32 iLoopFlg                   = 0;

    UINT32 iCharCount               = 0;

    UINT8 *pIdentify                   = NULL;

 

    // fopen

    fp = fopen("Example.txt", "r");    // 在当前工程目录下有一个有具体内容的文件Example.txt

    if (fp == NULL)

    {

        printf("Open the file failed!\n");

        return 1;

    }

 

    // fgetc

    if ((cSingleChar = fgetc(fp)) != EOF)

    {

        printf("%c\n", cSingleChar);

        fclose(fp);                   // 只读取第一个字符

    }

    else

    {

        printf("The file is empty!\n");

        fclose(fp);

    }

 

    // fgets

    fgets(szString, 100, fp);

    if (strlen(szString) != 0)

    {

        printf("%s\n", szString);

    }

    else

    {

        printf("The file is empty!\n");

    }

    fclose(fp);

   

    // fputc

    for (iLoopFlg = 0; iLoopFlg < 27; iLoopFlg ++)

    {

        cSingleChar = fputc(szAlphabeticSet[iLoopFlg], fp);

        if (cSingleChar == EOF)

        {

            printf("Input %c to file failed!\n", szAlphabeticSet[iLoopFlg]);

            fclose(fp);

            return 1;

        }

    }

    printf("Input to file successfully!\n");

    fclose(fp);

 

    // fputs

    iCharCount = fputs(szAlphabeticSet, fp);

    if (iCharCount == EOF)

    {

        printf("Input %s to file failed!\n", szAlphabeticSet);

        fclose(fp);

        return 1;

    }

    printf("Input to file successfully! Content = %s.\n", szAlphabeticSet);

    fclose(fp);

 

    // fread

    iCharCount = fread(szAlphabeticSet, 1, 26, fp);

    if (iCharCount == EOF)

    {

        printf("Read from file failed!\n");

        fclose(fp);

        return 1;

    }

    printf("Read from file successfully! Content = %s.\n", szAlphabeticSet);

    fclose(fp);

 

    // fseek

    iFileDescription = fseek(fp, 5, SEEK_SET);

    if (iFileDescription == 0)

    {

        printf("offset = %d\n", ftell(fp));

    }

    fclose(fp);

 

    // fwrite

    iCharCount = fwrite(szAlphabeticSet, 1, 26, fp);

    if (iCharCount == EOF)

    {

        printf("Write into file failed!\n");

        fclose(fp);

        return 1;

    }

    printf("Write into file successfully! Content = %s.\n", szAlphabeticSet);

    fclose(fp);

 

    // getc

    cSingleChar = getc(fp);

    if (cSingleChar != EOF)

    {

        printf("The got char is %c.\n", cSingleChar);

        fclose(fp);                   // 只读取第一个字符

    }

    else

    {

        printf("The file is empty!\n");

        fclose(fp);

        return 1;

    }

 

    // getchar与putchar

    cSingleChar = getchar();

    putchar(cSingleChar);

    printf("\n");

   

    // gets

    pIdentify = gets(szAlphabeticSet);

    if (pIdentify != NULL)

    {

        printf("The got string is %s.\n", szAlphabeticSet);

    }

    else

    {

        printf("Get string from scream failed!\n");

        return 1;

    }

   

    // putc

    cSingleChar = putc('a', fp);

    if (cSingleChar == EOF)

    {

        printf("Input to file failed!\n");

        fclose(fp);

        return 1;

    }

    printf("Input to file successfully!\n");

    fclose(fp);

 

    // putc与putchar

    cSingleChar = putc('a', fp);

    if (putchar(cSingleChar) == EOF)

    {

        printf("Input to scream failed!\n");

        return 1;

    }

    printf("\n");

    printf("Input to scream successfully!\n");

 

    // getc

    cSingleChar = getc(fp);

    if (cSingleChar != EOF)

    {

        printf("The got char is %c.\n", cSingleChar);

        fclose(fp);                   // 只读取第一个字符

    }

    else

    {

        printf("The file is empty!\n");

        fclose(fp);

        return 1;

    }

   

    return 0;

}

 

 

(欢迎访问南邮BBS:http://bbs.njupt.edu.cn/)
(欢迎访问重邮BBS:http://bbs.cqupt.edu.cn/nForum/index)

(本系列文章每周更新两篇,敬请期待!本人微博:http://weibo.com/zhouzxi?topnav=1&wvr=5,微信号:245924426,欢迎关注!)

 

时间: 2024-11-01 08:19:33

让你提前认识软件开发(18):C语言中常用的文件操作函数总结及使用方法演示代码的相关文章

提前认识软件开发(33) 数据操纵语言(DML)

数据操纵语言(Data Manipulation Language,DML)包括insert.delete和update语句,用于增.删.改数据. 本文用以下的表tb_employeeinfo作为例子加以说明: create table tb_employeeinfo ( employeeno varchar(20) not null, -- 员工工号 employeename varchar(20) not null, -- 员工姓名 employeeage int null -- 员工年龄

提前认识软件开发(22) shell脚本中的文件操作

编写shell脚本时,经常会涉及到对文件的操作,比如从文件中读取一行数据.向文件追加一行数据等.完成文件读写操作的方法有很多,了解各种命令下文件操作的执行情况,有助于开发人员在不同使用场景下选择合适的命令. 本文以实际的shell脚本为例,介绍了对文件进行操作的不同方法,为相关开发工作提供了参考. 一.概述 在某些软件项目的需求文档中,要求程序一次性读或写的数据规模较大,可达1000万行级,这就涉及到对程序执行方法和效率等的考虑. 本文比较了不同shell命令在对文件进行读或写操作过程中执行效率

提前认识软件开发(14):程序中的算法

算法(Algorithm),是程序的灵魂.著名计算机科学家.图灵奖获得者沃思曾提出过一个公式:数据结构+算法=程序.可见,算法在程序中占有非常重要的地位. 在实际的软件开发项目中,不管是有意设计或是无意为之,我们几乎随时在和算法打交道.小到定义一个变量,大到编写一个函数,这些都是算法的实现过程. 本文以作者实际项目工作为背景,介绍算法在C程序中的应用. 1.算法概述 什么是算法呢?先来看一看一些计算机书籍中的定义. 经典书籍<算法导论>(Cormen等著,机械工业出版社)中,作者认为算法是一系

提前认识软件开发(31) 数据库脚本中的begin与end

在数据库脚本中,begin与end是一对奇怪的单词.缺少它们,某些代码看起来会让人一头雾水:添加它们,代码的结构瞬间就清晰了. 确实,begin与end作为代码语句的开始和结束标志,可以让脚本程序的逻辑明确,易于阅读. begin与end主要用在以下地方: 1. if.else.else if.while等语句中 if.else.else if.while等语句要自占一行,执行语句不得紧跟其后,不论执行语句有多少都要加语句块标志begin-end. 脚本文件中的begin和end应独占一行并且位

提前认识软件开发(30) 数据库脚本中的空行与空格

在数据库脚本中,空行与空格起着"锦上添花"的作用.恰当地使用它们,可以提高代码的规范性及可阅读性,进而提升数据库的编程效率. 1. 空行 空行起着分隔脚本段落的作用,适当的空行可以使脚本的布局更加的清晰.空行的作用有以下几个: (1) 用于分隔两个数据表的创建脚本 示例: create table tb_example1 ( [表内容实现代码] ) go -- 空行 create table tb_example2 ( [表内容实现代码] ) go (2) 用于分割两个存储过程的创建脚

提前认识软件开发(28) 数据库存储过程中的重要表信息的保存

1. 存储过程中的重要表信息的保存 在很多存储过程中,会涉及到对表数据的更新.插入或删除等,为了防止修改之后的表数据出现问题,同时方便追踪问题,一般会为一些重要的表建立一个对应的debug表.这个debug表中的字段要包括原表的所有字段,同时要增加操作时间.操作码和操作描述等字段信息. 例如,在某项目中,包括了如下一个重要的表tb_XXX: create table tb_XXX ( AAA varchar(30) not null, -- AAA BBB varchar(30) not nul

PHP开发中常用的字符串操作函数

1,拼接字符串 拼接字符串是最常用到的字符串操作之一,在PHP中支持三种方式对字符串进行拼接操作,分别是圆点.分隔符{}操作,还有圆点等号.=来进行操作,圆点等号可以把一个比较长的字符串分解为几行进行定义,这样做是比较有好处的. 2,替换字符串 在PHP这门语言中,提供了一个名字叫做substr_replace()的函数,该函数的作用可以快速的完成扫描和编辑文本内容较多的字符串替换功能.他的语法格式: mixed substr_replace(mixed $string,string $repl

PHP开发中常用的字符串操作函数_php技巧

1,拼接字符串 拼接字符串是最常用到的字符串操作之一,在PHP中支持三种方式对字符串进行拼接操作,分别是圆点.分隔符{}操作,还有圆点等号.=来进行操作,圆点等号可以把一个比较长的字符串分解为几行进行定义,这样做是比较有好处的. 2,替换字符串 在PHP这门语言中,提供了一个名字叫做substr_replace()的函数,该函数的作用可以快速的完成扫描和编辑文本内容较多的字符串替换功能.他的语法格式: mixed substr_replace(mixed $string,string $repl

提前认识软件开发(12) 配置文件读取及文件操作

在通信领域的软件开发项目中,C语言是主流的编程语言,而文件操作在其中又占有很重要的地位.此外,为了体现产品的灵活性,可添加配置文件对某些重要的参数进行按需配置.这就要求程序能够准确读取到各个配置项的值. 本文以一个实际的小软件为例,介绍了C语言中配置文件的读取方法和重要的文件操作函数的使用方法,为相关软件开发项目提供了有益的参考. 1.前言 在一般的软件项目中,常常需要用C语言对文件进行操作.在诸如对账之类的程序中,尤其如此.而C语言中有关文件操作的函数多达数十种,熟悉常用函数(如fopen.f