Linux学习之应用开发阶段(标准IO一)

言之者无罪,闻之者足以戒。 ——《诗序》
上一篇文章我们说到了fclose()函数,fclose()函数调用成功返回0,失败返回EOF,并设置errno;
fclose()函数有一个很重要的功能:在一个文件被关闭之前,刷新缓存中的数据。如果标准IO库已经为该流自动分配了一个缓存,则释放此缓存。
1、读写函数:
三类读写函数:
第一类:行缓存 遇到换行符(\n)或写满缓存时,即调用系统调用函数
读:fgets,gets,printf,fprintf,sprintf
写:fputs,puts,scanf
一个字符的读写,是否是行缓存?
读:fgetc,getc,getchar
写:fputc,putc,putchar
第二类:无缓存 只要用户调用这个函数,就会将其内容写到内核中
stderr函数
下面的程序是可以输出到屏幕的三种情况:

#include <stdio.h>
int main()
{
        //fputs("hello Linux\n",stdout);
        //fputs("hello Linux",stdout);
        fputs("hello Linux",stderr);

        //fflush(stdout);
        while(1);
        return 0;
}

第一种是直接加换行符;第二种是强制刷新写入;第三种就是标准stderr

第三类:全缓存 只有写满缓存才调用系统调用函数
读:fread
写:fwrite
1) 行缓存的读写函数fgets和fputs
char*fgets(char *s,int size,FILE *stream)
第一个参数:缓存,即读到哪里去
第二个参数:读多少个字节
第三个参数:从什么地方读
返回值:若成功则为s(缓存的地址),若已经处于文件的尾端或出错则为null
int fputs(const char *s,FILE *stream)
第一个参数:缓存,即写什么内容
第二个参数:写到哪里去
若成功则为非负值,若出错则为EOF(等价于-1)
注意:我们前面说fputs是一个行缓存的函数,遇到换行符或写满缓存时才会调用系统缓存函数,但是我们测试的时候如果程序的末尾有fclose()函数,那么即使没有换行符也没有写满它也会调用系统函数,这是因为上面我们所说过的fclose()函数的一个重要的功能。
2)行缓存的读写函数gets和puts

char *gets(char *s)
int puts(const char *s)
gets函数与fgets函数的区别:
(1)使用gets()函数时不能指定缓存的长度,这样就可能造成缓存越界(如若该行长于缓存长度),写到缓存之后的存储空间中,从而产生不可预料的结果
(2)gets()函数只能从标准输入中读
(3)gets()函数不将新行符(换行符)存入缓存中,fgets()函数将新行符存入缓存中
puts函数与fputs函数的区别:
(1)puts()只能向标准输出写入
(2)puts函数输出会添加一个新行符,fputs函数不会添加
下面的程序将上面的内容做一下对比:

#include <stdio.h>
#include <string.h>
int main()
{
        char buf[128]={0};
        int len;
        //get(buf);
        fgets(buf,128,stdin);
        len=strlen(buf);
        printf("len=%d\n",len);
        puts(buf);
        //fputs(buf,stdout);
        return 0;
}
     

2、刷新缓存函数:
fflush(FILE *fp)
把库函数中的缓存的内容强制写到内核中。

3、调整读写指针函数:
1)、fseek()参数与lseek是一样的但是返回值不同
lseek()的返回值:当前文件的位置指针
fseek()的返回值:成功返回0 ,失败返回-1
关于fseek()的参数问题请看我的另一篇文章**(https://blog.csdn.net/weixin_42994525/article/details/82978879)**
2)、rewind(FILEfp)用于设定流的文件位置指示为文件开始,该函数调用成功无返回值。
rewind()等价于(void)fseek(fp,0,SEEK_SET)
3)、ftell(FILE
fp)用于取得当前的文件位置,调用成功则为当前文件位置指示,若出错则为-1
下面粘贴出一个程序说明调整指针函数:

#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
        FILE *fp;
        char buf[]="hello Linux";
        char readbuf[128]={0};
        fp=fopen("./a.c","w+");
        if(fp==NULL)
        {
                printf("open file a.c failure\n");
                return -1;
        }
        printf("open file a.c sucess\n");
        fputs(buf,fp);
        //fseek(fp,0,SEEK_SET); 
        rewind(fp);
        fgets(readbuf,128,fp);
        printf("readbuf:%s\n",readbuf);
        fclose(fp);
        return 0;
}
   

注意:一般我们是先写然后再去读,但是如果写完之后直接读取那么读取的结果就是错误的,所以在写过之后读取之前我们需要把文件指针指向要开始读取的位置,这样才能得到正确的结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值