文件IO

本文详细介绍了文件操作的基本方式,包括各种文件打开模式如只读、只写等,以及如何使用fopen、fclose等函数进行文件的读写和关闭操作。同时,文章还讲解了错误处理方法及如何使用perror和strerror函数解释错误原因。

"r"

    只读,文件必须已存在
"w"

    只写,如果文件不存在则创建,如果文件已存在则把文件长度截断(Truncate)为0字节再重新写,也就是替换掉原来的文件内容
"a"

    只能在文件末尾追加数据,如果文件不存在则创建
"r+"

    允许读和写,文件必须已存在
"w+"

    允许读和写,如果文件不存在则创建,如果文件已存在则把文件长度截断为0字节再重新写
"a+"

    允许读和追加数据,如果文件不存在则创建

注意除了r不自动创建文件外,其他都会自动创建文件

在打开一个文件时如果出错,fopen将返回NULL并设置errno,errno稍后介绍。在程序中应该做出错处理,通常这样写:

把文件指针传给fclose可以关闭它所标识的文件,关闭之后该文件指针就无效了,不能再使用了。如果fclose调用出错(比如传给它一个无效的文件指针)则返回EOF并设置errno,errno稍后介绍,EOF在stdio.h中定义:

那为什么printf和scanf不用打开就能对终端设备进行操作呢?因为在程序启动时(在main函数还没开始执行之前)会自动把终端设备打开三次,分别赋给三个FILE *指针stdin、stdout和stderr

比较好的办法是用perror或strerror函数将errno解释成字符串再打印

学线程库时我们会看到,有些函数的错误码并不保存在errno中,而是通过返回值返回,就不能调用perror打印错误原因了,这时strerror就派上了用场:

int fgetc(FILE *stream);
int getchar(void);
返回值:成功返回读到的字节,出错或者读到文件末尾时返回EOF

fputs(strerror(n), stderr);

#include <stdio.h>

int fputc(int c, FILE *stream);
int putchar(int c);
返回值:成功返回写入的字节,出错返回EOF

从终端设备输入时有两种方法表示文件结束,一种方法是在一行的开头输入Ctrl-D(如果不在一行的开头则需要连续输入两次Ctrl-D),另一种方法是利用Shell的Heredoc语法:

$ ./a.out <<END
> hello
> hey
> END
hello
hey

 

#include <stdio.h>

int fseek(FILE *stream, long offset, int whence);
返回值:成功返回0,出错返回-1并设置errno

long ftell(FILE *stream);
返回值:成功返回当前读写位置,出错返回-1并设置errno

void rewind(FILE *stream);

fseek的whence和offset参数共同决定了读写位置移动到何处,whence参数的含义如下:

SEEK_SET

    从文件开头移动offset个字节
SEEK_CUR

    从当前位置移动offset个字节
SEEK_END

    从文件末尾移动offset个字节

#include <stdio.h>

char *fgets(char *s, int size, FILE *stream);
char *gets(char *s);
返回值:成功时s指向哪返回的指针就指向哪,出错或者读到文件末尾时返回NULL

注意,对于fgets来说,'\n'是一个特别的字符,而'\0'并无任何特别之处,如果读到'\0'就当作普通字符读入。如果文件中存在'\0'字符(或者说0x00字节),调用fgets之后就无法判断缓冲区中的'\0'究竟是从文件读上来的字符还是由fgets自动添加的结束符,所以fgets只适合读文本文件而不适合读二进制文件,并且文本文件中的所有字符都应该是可见字符,不能有'\0'。

#include <stdio.h>

int fputs(const char *s, FILE *stream);
int puts(const char *s);
返回值:成功返回一个非负整数,出错返回EOF

缓冲区s中保存的是以'\0'结尾的字符串,fputs将该字符串写入文件stream,但并不写入结尾的'\0'。与fgets不同的是,fputs并不关心的字符串中的'\n'字符,字符串中可以有'\n'也可以没有'\n'。puts将字符串s写到标准输出(不包括结尾的'\0'),然后自动写一个'\n'到标准输出。

转载于:https://www.cnblogs.com/275095923/archive/2013/01/15/2861413.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值