前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C文件操作1】如何写入读取?fopen的6种组合参数怎么用?

【C文件操作1】如何写入读取?fopen的6种组合参数怎么用?

作者头像
xxpcb
发布2021-05-14 10:49:22
1.8K0
发布2021-05-14 10:49:22
举报
文章被收录于专栏:码农爱学习的专栏

C语言中文件操作,即文件打开,文件写入、文件读取、文件关闭等。

在使用这些功能时,需要了解其基本的使用规则,如:

文件读写前,必须先使用fopen函数打开文件。

使用fopen打开时,还要指明文件的打开的参数,是要读呢还是写呢?这些参数如果不注意,比如直接使用"w"参数打开一个已存在的文件,则里面的内容会先被清空,如果还想要之前的文件中的内容,那也已经被清空了!

01 文件操作基础函数

fopen

若要对文件进行读写操作,第一步需要使用fopen()函数 fopen()函数用于打开指定路径的文件,获取指向该文件的指针

函数原型:

代码语言:javascript
复制
/** @func:  fopen
*   @brief: 打开文件
*   @para:  [path]:文件路径,如:"E:\Test\test.txt"
*           [mode]:文件打开方式(r w a r+ w+ a+ rb wb ab ...具体见下面表格)
*   @return:文件打开成功,则指向该流的文件指针就会被返回
*           文件打开失败,则返回NULL,并把错误代码存在errno中
*/
FILE * fopen(const char * path,const char * mode);

fopen打开方式的参数

打开文件的参数,一共6种符号,包括2部分,第1部分的指定读还是写(r\w\a),第2部分指定是对第1部分的补充(t/b/+)

  • 参数第1部分(r\w\a)

字符

含义

解释

r

read

只读(打开文件),文件必须存在

w

write

只写(创建文件),文件若已存在,则文件会先被清空

a

append

末尾追加写入,文件若不存在,则先创建

  • 参数第2部分(t\b\+)

字符

含义

解释

t

text

读写文本文件

b

binary

读写二进制文件

+

read/write

即能读也能写

注意: 参数第1部分的必须要有的,第2部分可以省略,但省略后,会有其默认的含义 未指明是读文本还是二进制,则默认为读文本文件

默认规则

代码语言:javascript
复制
"r" = "rt", 因为默认打开text
"w" = "wt", 因为默认打开text
"a" = "at", 因为默认打开text
"r+" = "rt+", 因为默认打开text
"w+" = "wt+", 因为默认打开text
"a+" = "at+", 因为默认打开text

思考疑问1:r+w+的作用有区别吗? r表示读,w表示写,都补充一个+,表示既能读也能写,看起来作用好像是一样。 但,区别就在于第1部分的rw,一个是文件必须存在,一个是不存在则会先创建 疑问2:ww+的作用有区别吗?aa+的作用有区别吗? w表示擦除写入,a表示追加写入,都补充一个+,赋予它们读的功能 wa既然都能写了,还不能读吗,还要添加一个+才能读?是的!

fread

函数原型:

代码语言:javascript
复制
/** @func:  fread
*   @brief: 从文件读取
*   @para:  [buffer]:指向数据块的指针
*           [size]:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
*           [count]:数据个数
*           [stream]:文件指针,如fp
*   @return:实际读取的个数
*/
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);

fread的返回值随着调用格式的不同而不同

调用格式1fread(buf,sizeof(buf),1,fp);,将整个buf数据作为1个数据读取,则读取的个数是1 读取成功返回值为1 调用格式2fread(buf,1,sizeof(buf),fp);,将1Byte作为1个数据读取,则读取个数是sizeof(buf) 读取成功返回实际写入的数据个数(单位为Byte)

fwrite

fwrite()函数用于将内存区域中的数据写入到本地文本

函数原型:

代码语言:javascript
复制
/** @func:  fwrite
*   @brief: 向文件写入
*   @para:  [buffer]:指向数据块的指针
*           [size]:每个数据的大小,单位为Byte(例如:sizeof(int)就是4)
*           [count]:数据个数
*           [stream]:文件指针,如fp
*   @return:实际写入的个数
*/
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

fwrite的返回值随着调用格式的不同而不同

调用格式1fwrite(buf,sizeof(buf),1,fp);,将整个buf数据作为1个数据写入,则写入个数是1 成功写入返回值为1 调用格式2fwrite(buf,1,sizeof(buf),fp);,将1Byte作为1个数据写入,则写入个数是sizeof(buf) 成功写入则返回实际写入的数据个数(单位为Byte)

fclose

写完数据后要调用fclose()关闭流,不关闭流的情况下,每次读或写数据后,文件指针都会指向下一个待写或者读数据位置的指针。

函数原型:

代码语言:javascript
复制
/** @func:  fclose
*   @brief: 关闭文件
*   @para:  [stream]:文件指针,如fp
*   @return:关闭成功返回0,关闭失败返回EOF
*/
int fclose( FILE *stream );

02 使用示例

基础示例

打开&写入

小技巧: 用malloc函数申请区域时是申请的一片char*区域,通过强制类型转换后可装任意类型数据

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

#define DATA_SIZE 100
 
int main()
{
    unsigned char *pRawData = NULL;
    int *pData = NULL;
    
    /*使用malloc申请一块内存*/
    pRawData = (unsigned char *)malloc(sizeof(int) * DATA_SIZE);
    /*将该块内存强制转换为unsigned int*/
    pData = (int *) pRawData;
    
    /*对该块内存进行赋值 */
    int i = 0;
    for(i=0; i<DATA_SIZE; i++)
    {
        pData[i] = i; 
    }
    
    /*打开*/
    FILE *fp = fopen("../test1.bin","wb");
    if(NULL == fp)
    {
        printf("open file fail\r\n");
        goto end;
    }
    
    /*写入*/
    size_t cnt = fwrite(pData, sizeof(int), DATA_SIZE, fp);
    if(DATA_SIZE != cnt)
    {
        printf("write file fail\r\n");
        fclose(fp);
        goto end;
    }
    
    /*关闭*/
    fclose(fp);
    printf("file write ok\r\n");
    
 end:
    free(pRawData);/*malloc用完后要free*/
    system("pause");
    
    return 0;
}

打开&读取

注意: 以2进制的形式写入,读取时也必须是以2进制形式读取!否则会读取到错误的数据

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

#define DATA_SIZE 100
 
int main()
{
    int pData[DATA_SIZE];
    
    /*打开*/
    FILE *fp = fopen("../test1.bin","rb");/*写入的是bin, 读取的也必须是bin*/
    if(NULL == fp)
    {
        printf("open file fail\r\n");
        goto end;
    }
    
    /*读取*/
    size_t cnt = fread(pData, sizeof(int), DATA_SIZE, fp);
    if(DATA_SIZE != cnt)
    {
        printf("read file fail, read size:%d\r\n", cnt);
        fclose(fp);
        goto end;
    }
    printf("data[30]:%d\r\n", pData[30]);/*打印出其中一个数据*/
    
    /*关闭*/
    fclose(fp);
    printf("file read ok\r\n");
    
 end:
    system("pause");
    
    return 0;
}

特殊示例

写入结构体

代码语言:javascript
复制
/*定义结构体*/
typedef struct
{
	char name[256];
	unsigned int page;
	float price;	
}BOOK;
 
/*声明实例化一个结构体对象*/
BOOK book1 = {
    .name = "C语言基础",
    .page = 320,
    .price = 25.0,
};

写入方式:

代码语言:javascript
复制
/*打开*/
FILE *fp1 = fopen("../test2.bin","wb");
if(NULL == fp1)
{
    printf("open file fail\r\n");
    goto end;
}

/*写入*/
size_t cnt1 = fwrite(&book1, 1, sizeof(BOOK), fp1);
if(sizeof(BOOK) != cnt1)
{
    printf("write file fail\r\n");
    fclose(fp1);
    goto end;
}

读取方式:

代码语言:javascript
复制
/*打开*/
FILE *fp2 = fopen("../test2.bin","rb");
if(NULL == fp2)
{
    printf("open file fail\r\n");
    goto end;
}

/*读取*/
size_t cnt2 = fread(&myBook, 1, sizeof(BOOK), fp2);
if(sizeof(BOOK) != cnt2)
{
    printf("read file fail\r\n");
    fclose(fp2);    
    goto end;
}
printf("myBook info: name:%s, page:%d, price:%.2f\r\n",
       myBook.name, myBook.page, myBook.price);

03 总结

读(fread)或写(fwrite)文件前,要先打开(fopen)文件。

读(fread)或写(fwrite)文件后,要关闭(fclose)文件。

打开(fopen)文件时,要特别注意打开的参数指定。

r参数打开文件时,该文件必须存在。

w参数打开文件时,该文件会被先清空,若文件不存在会先创建。

a参数打开文件时,写入内容将会在文件尾部添加,若文件不存在会先创建。

b参数打开文件时,打开的是二进制文件。

t参数打开文件时,或不指明b或t,则打开的是文本文件。

+参数打开文件时,就有了读与写的功能。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-05-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农爱学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01 文件操作基础函数
  • fopen
  • fread
  • fwrite
  • fclose
  • 02 使用示例
  • 基础示例
    • 打开&写入
      • 打开&读取
      • 特殊示例
        • 写入结构体
        • 03 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档