IO进程线程(二)标准IO之fprintf/sprintf/snprintf fread/fwrite fseek/rewind/ftell

一、fprintf/spritnf/snprintf

(一)fprintf函数

1. 定义

#include <stdio.h>
int fprintf(FILE *stream, const char *format, ...);
功能:将格式化的字符串写入文件中
参数:
    stream:文件指针
    format:格式
    ...:可变参
返回值:
    成功  实际格式化的字节数
    失败  返回一个负数

(二) sprintf函数

1. 定义

#include <stdio.h>
int sprintf(char *str, const char *format, ...);
功能:将格式化的字符串写入str指向的内存中
参数:
    str:用来存放内容的空间的首地址
    format:格式
    ...:可变参
返回值:
    成功  实际格式化的字节数
    失败  返回一个负数

2. 使用示例

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char buff[20];
    sprintf(buff,"buff size is %ld\n",sizeof(buff));
    printf("%s",buff);
    return 0;
}

输出结果:
在这里插入图片描述

  • 注:sprintf不会对越界进行检查,会弹出一个警告。越界访问结果不可预知

在这里插入图片描述

(三) snprintf

1. 定义

#include <stdio.h>
int snprintf(char *str, size_t size, const char *format, ...);
功能:将格式化的字符串写入str指向的内存中
    最多拷贝 size-1 个字节 最后会有一个 '\0'
参数:
    str:用来存放内容的空间的首地址
    format:格式
    ...:可变参
返回值:
    成功  实际格式化的字节数
    失败  返回一个负数

2. 使用示例

#include <stdio.h>

int main(int argc, char const *argv[])
{
    char buff[20];
    snprintf(buff,sizeof(buff)-1,"buff size is %ldaaaaa\n",sizeof(buff));
    printf("%s",buff);
    return 0;
}

当格式化字符串的长度超出缓存区的范围,仍会报警告,但是实际写入的长度是根据传入的参数size决定的
在这里插入图片描述

  • 注:
  • size个字节(包含’\0’),即最多写入size-1个字节
函数fprintfsprintfsnprintf
头文件stdio.hstdio.hstdio.h
参数FILE *stream,char *formatchar *str,char *formatFILE *stream,size_t size,char *format
返回值成功,返回实际写入的格式化的字节数量;失败,返回一个负数成功,返回实际写入的格式化的字节数量;失败,返回一个负数成功,返回实际写入的格式化的字节数量;失败,返回一个负数
功能将格式化字符串写入stream文件中将格式化字符串写入str指向的内存空间中将格式化字符串中最多size-1个字符写入str指向的内存空间中

二、fread/fwrite函数

(一) fread函数

1. 定义

#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
    在文件stream中读取nmemb个size大小的项目到ptr指向的内存中
参数:
    ptr:用来保存读到的内容的缓冲区的首地址
    size:每一项的大小 单位:字节 
            一般使用时 都将其置1 这样 nmemb就是 字节数了
    nmemb:想要读取的项目数
    stream:文件指针
返回值:
    成功 实际读到的项目数
    失败 小于项目数的数(或者0)
  • :注意:fread不会区分出错和文件结束
  • 需要调用者使用 feof 和 ferror 来区别
    if(feof(fp)) 如果为真 说明文件结束了
    if(ferror(fp)) 如果为真 说明出错了

(二) fwrite函数

1. 定义

#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
    把ptr指向的空间中的内容写入nmemb个size大小到文件stream中
参数:
    ptr:要写入的内容的首地址
    size:每一项的大小 单位:字节 
            一般使用时 都将其置1 这样 nmemb就是 字节数了
    nmemb:想要写入的项目数
    stream:文件指针
返回值:
    成功 实际写入到的项目数
    失败 小于项目数的数(或者0)
  • 项目数的大小要依据实际情况而定,在使用strlen和sizeof时要多加注意
  • 我们的文件是文本文件,只能以字符形式显示内容,写入整数时看到的可能是乱码,但是确实写进去了,再以整数形式读出仍是原整数
  • 大端与小端是以字节为单位
2. 使用示例

功能需求:使用fwrite和fread复制文件,要求从命令行传参

需求分析
fwrite函数会返回读取的字符串数量。

代码实现

#include <stdlib.h>
#include <stdio.h>

int main(int argc, char const *argv[])
{
    if(3 != argc){
        printf("Usage: ./a.out src dest\n");
        exit(-1);
    }

    FILE *src_fp=fopen(argv[1],"r");
    if(NULL == src_fp){
        perror("fopen src file error");
        exit(-1);
    } 
    FILE *dest_fp=fopen(argv[2],"w");
    if(NULL == dest_fp){
        perror("fopen dest file error");
        exit(-1);
    } 
    char buff[10]={0};
    int c=0;
    int nbyte=0;
    while(0 < (nbyte = fread(buff,1,sizeof(buff),src_fp))){
        if(nbyte != fwrite(buff,1,nbyte,dest_fp)){
            printf("fwrite error\n");
            exit(-1);
        }
    }
    printf("复制成功\n");
    return 0;
}
函数freadfwrite
头文件stdio.hstdio.h
参数void *ptr, size_t size, size_t nmemb, FILE *streamvoid *ptr, size_t size, size_t nmemb, FILE *stream
返回值size_t 成功,返回实际读取的项目数;失败返回小于项目数的数,或者0size_t 成功,返回实际写入的项目数;失败返回小于项目数的数,或者0
功能读取stream文件中nmemb个size大小的项目到ptr指向的空间将ptr指向的内容写入nmemb个size大小的项目写入到stream文件中
备注fread函数对文件尾还是出错没有区分,需要借助feof和ferror来判断
  • 注:size_t 即 long unsigned int 无符号长整型

三、光标位置fseek/rewind/ftell

(一) fseek函数

#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
功能:
    设置光标位置
参数:
    stream:文件指针
    offset:偏移量 (字节为单位)
        0  不偏移
        >0  向后偏移
        <0  向前偏移
    whence:相对位置
        SEEK_SET  相对于文件开头
        SEEK_CUR  相对于当前位置
        SEEK_END  相对于文件结尾
返回值:
    成功  0
    失败  -1  重置错误码

使用实例:
    fseek(fp, 0, SEEK_SET);//将光标定位到文件开头
    fseek(fp, 0, SEEK_END);//将光标定位到文件结尾
    fseek(fp, 10, SEEK_CUR);//将光标向后偏移10个字节
    fseek(fp, -10, SEEK_CUR);//将光标向前偏移10个字节
    fseek(fp, 10, SEEK_SET);//将光标定位到文件开头第10个字节
    fseek(fp, -10, SEEK_END);//将光标定位到文件倒数第10个字节
  • 注:
  • 相对于文件开头向前偏移会报错,返回-1
  • 相对于文件结尾将光标向后偏移,如果写入数据,就会将文件撑大,原文件尾和写入数据的之间会使用NULL填充,不会报错,但是一般不这样使用。

(二) rewind

#include <stdio.h>
void rewind(FILE *stream);
功能:将光标定位到文件开头
参数:stream:文件指针
返回值:无

(三) ftell

#include <stdio.h>
long ftell(FILE *stream);
功能:获取当前光标距离文件开头的偏移量
参数:stream:文件指针
返回值:
    成功  偏移量
    失败  -1  重置错误码
函数fseekrewindftell
头文件stdio.hstdio.hstdio.h
参数FILE *stream, long offset, int whenceFILE *streamFILE *stream
返回值成功返回0;失败返回-1,重置错误码无返回值成功,返回偏移量;失败返回-1,重置错误码
功能设置光标位置将光标定位到文件开头获取当前光标距离文件开头的偏移量
  • 23
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值