IO操作之标准IO

本文详细介绍了Linux标准IO操作,包括fopen函数的使用、文件权限问题、fclose函数、fseek和rewind函数的功能及原型,ftell函数、fflush函数的作用,以及标准IO中的读写函数和错误检测函数feof与ferror。最后通过一个综合测例展示了如何实现cat命令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在前面的文章中,我们已经对文件IO进行了简单的介绍。今天,我们便对另外一种IO操作相关的函数—标准IO进行初步的学习。

fopen函数

作用

与文件IO中的open函数的作用一致,fopen函数的作用也是打开一个文件。只是在形式上有所不同。

函数形式

函数原型FILE *fopen(const char *path, const char *mode)
头文件#include <stdio.h>
参数含义如下
返回值成功:返回一个文件流指针 失败:返回NULL

其中,参数path指的是需要打开文件的路径和文件的文件名,而参数mode则指的是以什么方式打开该文件,可选的值为:

"r":以只读的方式打开文件
"r+":以读写的方式打开文件
"w":以覆盖的方式打开文件或者创建一个文件指针指向文件开头的可写的新文件
"w+":以覆盖的读写方式打开文件或者创建一个文件指针指向文件开头的新文件
"a":以追加的方式打开文件(不会覆盖文件之前的内容)或者创建一个文件指针指向文件末尾的新文件
"a+":以追加的方式打开文件或者创建一个新的文件,当读取文件的内容时,文件指针将指向文件开头,但是写入内容时,文件指针将指向文件的结尾

文件的权限问题

与open函数不同,fopen函数在创建一个新文件时,并没有提供指定文件权限的参数。所以,利用fopen函数创建的新文件的权限是默认的,为0666与取反后的文件掩码相与的结果。比如:当文件掩码为0222时,那么利用fopen函数创建的文件权限为:0666&(~0222) = 0444
当然,如果后续需要更改文件的权限,我们可以利用chmod等命令进行相应的更改。

测例

利用fopen函数,以追加的方式新建一个文件:

#include <stdio.h>
int main(int argc,char* argv[])
{
  	FILE* pd;
  	pd = fopen(argv[1],"a+");
 	if(NULL == pd)
  	{
     printf("open file %s failed!\n",argv[1]);
  	}
   fclose(pd);
   return 0;
}

fclose函数

作用

fclose函数的作用与文件IO中的close函数的作用是一致的,作用都是关闭打开的文件,只是两者的形式不同。

函数原型

函数原型int fclose(FILE *fp)
头文件#include <stdio.h>
参数含义如下
返回值成功:返回0 失败:返回-1

其中,参数fp即利用fopen函数返回的文件流指针。
与文件IO操作类似,当利用fopen函数打开一个文件之后,一定要在相应的位置利用fclose函数关闭该文件。

fseek函数和rewind函数

作用

与文件IO函数类似,标准IO也存在文件指针的概念。所以,在实际应用中,当用户想要指定操作的文件指针的位置时,便需要使用fseek函数或者rewind函数,对文件指针的位置进行更改。

rewind函数原型

rewind函数的作用是将文件指针的位置调整到文件的开头处,其函数原型如下:

函数原型void rewind(FILE *stream)
头文件#include <stdio.h>
参数如下
返回值无返回值

其中,参数stream即利用fopen函数打开文件时返回的文件流指针。

fseek函数原型

对于标准IO操作而言,不仅可以使用rewind函数将文件指针的位置调整到文件的开头,同样也可以使用fseek函数,调整文件指针的位置到其他地方。该函数的原型如下:

函数原型int fseek(FILE *stream, long offset, int whence)
头文件<stdio.h>
参数如下
返回值成功:返回文件指针的位置 失败:返回-1

其中,参数stream即上述的文件流指针,参数whence即以什么地址为基准进行文件指针的调整,可选的参数为:

SEEK_SET:文件开头
SEEK_CUR://当前位置
SEEK_END://文件结尾

参数offset指的便是文件指针的偏移值,正数意味着向右进行偏移,负数则意味着向左进行偏移。
比如:

rewind(pd);//将文件指针调整到文件开头
fseek(pd,-2,SEEK_END);//将文件指针的位置调整到文件的倒数第二个位置处
fseek(pd,0,SEEK_SET);//将文件指针的位置调整到文件的开头处

有上述可知,rewind(pd)函数与fseek(pd,0,SEEK_SET)函数是等价的。

ftell函数

ftell函数的作用是获取文件当前文件指针的位置。
函数原型如下:

函数原型long ftell(FILE *stream)
头文件<stdio.h>
参数如下
返回值成功:返回文件指针的位置 失败:返回-1

其中,参数stream同样指的是文件流指针

fflush函数

无论是行缓存函数还是全缓存函数,当使用fflush刷新缓存时,均会强制将缓存中的内容写到内核的缓存中。

标准IO中的读写函数

在标准IO操作中,读写函数比较多,我们首先按照之前提到的缓存特性,对标准IO中的读写函数进行分类。
按照缓存的特性,我们可以将标准IO中的读写函数分为:

1、行缓存读写函数:
读函数:
fgets gets printf fprintf sprintf
写函数:
fputs puts scanf
2、全缓存读写函数:
读函数:
fread
写函数:
fwrite
3、无缓存读写函数:
stderr

由于标准IO函数中的读写函数较多,所以此处就不进行一一讲解了,而对在使用过程中需要注意的地方进行简单的总结:

1、fprintf、printf和sprintf函数之间的区别?
①fprintf函数可以将内容输出到一个文件或者标准输出上(一般为屏幕)
②printf函数只能将内容输出到标准输出上
③sprintf函数是将内容复制给一个字符串	

feof函数和ferror函数

在利用上述的读函数读取文件中的内容时,当读取到文件结尾或者读取文件失败时,读函数均会返回EOF。那么,在实际应用中,怎样判断到底是已经读取到了文件结尾,还是读取文件时发生了错误呢?我们可以利用feof函数或者ferror函数进行判断。feof函数的原型如下:

函数原型int feof(FILE *stream)
头文件<stdio.h>
参数如下
返回值返回非零值:已经到了文件结尾 返回零值:并没有到达文件结尾

其中,参数stream仍然是上述的文件流指针。
ferror函数的原型如下:

函数原型int ferror(FILE *stream)
头文件<stdio.h>
参数如下
返回值返回非零值:读写文件失败 返回零值:成功读写文件

其中,参数stream仍然是文件流指针。

综合测例

利用上面的标准IO函数或者相应的库函数,实现cat命令
cat命令的作用是显示一个文件中的内容:

 #include <stdio.h>
 #include <string.h>
 int main(int argc,char* argv[])
 {
     FILE* pd;
    char* write_buf = "Hello Linux";
    char read_buf[128] = {0};
    ssize_t write_num = 0,read_num = 0;
    pd = fopen(argv[1],"r");
    if(NULL == pd)
    {
         printf("open file %s failed!\n",argv[1]);
         return -1;
    }
    //write_num = fwrite(write_buf,sizeof(write_buf[0]),strlen(write_buf),pd);
    rewind(pd);
     while(1)
    {
      read_num = fread(read_buf,sizeof(read_buf[0]),128,pd);
       printf("%s",read_buf);
       if(read_num < 128)
       {
           break;
       }
     }
     printf("\n");
     fclose(pd);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值