C语言文件操作笔记-2

文件函数说明

此为基础篇文件操作,涉及基础使用函数:
fread、fwrite、fscanf、fprintf、remove、fseek、ftell、rewind、fgetpos、truncate、ftruncate等函数说明。

相关函数说明

fread

/*****************************
 * 函数名称:fread
 * 函数入口:
 *            ptr: 这是指向带有最小尺寸 size*nmemb 字节的内存块的指针。
 *            size:要读取大大小
 *            nmemb:读取次数
 *            stream:文件流
 * 函数出口:
 *         成功读取的元素总数会以 size_t 对象返回,size_t 对象是一个整型数据类型。如果总数与 nmemb 参数不同,则可能发生了一个错误或者到达了文件末尾。
 * 函数说明:
 *         读取文件指定 size*nmemb 字节内容放到ptr中,并返回读取大小
 * ***************************/
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

fwrite

/*****************************
 * 函数名称:fwrite
 * 函数入口:
 *            ptr: 这是指向要被写入的元素数组的指针。
 *            size:要写入大大小
 *            nmemb:写入次数
 *            stream:文件流
 * 函数出口:
 *         如果成功,该函数返回一个 size_t 对象,表示元素的总数,该对象是一个整型数据类型。如果该数字与 nmemb 参数不同,则会显示一个错误。
 * 函数说明:
 *         将ptr写入到文件中 size*nmemb 字节内容,并返回读取大小
 * ***************************/
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

fscanf

/*****************************
 * 函数名称:fscanf
 * 函数入口:
 *            format:这是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符。
 *            stream:文件流
 * 函数出口:
 *         如果成功,该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误,则返回 EOF。
 * 函数说明:
 *        从流 stream 读取格式化输入。具体与sscanf类似
 * ***************************/
int fscanf(FILE *stream, const char *format, ...);

fprintf

/*****************************
 * 函数名称:fprintf
 * 函数入口:
 *            format:这是 C 字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符。
 *            stream:文件流
 *            ...:参数
 * 函数出口:
 *         如果成功,则返回写入的字符总数,否则返回一个负数。
 * 函数说明:
 *         发送格式化输出到流 stream 中。
 * ***************************/
int fprintf(FILE *stream, const char *format, ...);

remove

/*****************************
 * 函数名称:remove
 * 函数入口:
 *             pathname 文件名称
 * 
 * 函数出口:
 *        执行成功返回0,失败返回-1,错误代码保存在errno中。
 * 函数说明:
 *        删除指定文件
 * ***************************/
 int remove(const char *pathname);

fseek

/*****************************
 * 函数名称:fseek
 * 函数入口:
 *            stream:文件流
 *            offset: 这是相对 whence 的偏移量,以字节为单位。
 *            whence:相对位置(SEEK_SET(文件头)、SEEK_CUR(文件当前位置)、SEEK_END(文件末尾))
 * 函数出口:
 *         如果成功,则该函数返回零,否则返回非零值。
 * 函数说明:
 *         设置流 stream 的文件位置为给定的偏移 offset,参数 offset 意味着从给定的 whence 位置查找的字节数。
 * ***************************/
 int fseek(FILE *stream, long int offset, int whence);

ftell

/*****************************
* 函数名称:ftell
* 函数入口:
*            stream:文件流
* 函数出口:
*         该函数返回位置标识符的当前值。如果发生错误,则返回 -1L,全局变量 errno 被设置为一个正值。
* 函数说明:
*         返回给定流 stream 的当前文件位置。
* ***************************/
long int ftell(FILE *stream);

rewind

/*****************************
 * 函数名称:rewind
 * 函数入口:
 *            stream:文件流
 * 函数出口:
 *         该函数不返回任何值。
 * 函数说明:
 *         设置文件位置为给定流 stream 的文件的开头。
 * ***************************/
void rewind(FILE *stream);

fgetpos

/*****************************
 * 函数名称:fgetpos
 * 函数入口:
 *            stream:文件流
 *             pos:这是指向 fpos_t 对象的指针,该对象包含了之前通过 fgetpos 获得的位置。
 * 函数出口:
 *        如果成功,该函数返回零值,否则返回非零值,并设置全局变量 errno 为一个正值,该值可通过 perror 来解释。
 * 函数说明:
 *        设置给定流 stream 的文件位置为给定的位置。参数 pos 是由函数 fgetpos 给定的位置。
 * ***************************/
int fsetpos(FILE *stream, const fpos_t *pos);

truncate/ftruncate

#include <unistd.h>
#include <sys/types.h>
/*****************************
 * 函数名称:truncate
 * 函数入口:
 *             path  文件路径
 *             length 指定文件剩余大小
 * 函数出口:
 *       执行成功则返回0, 失败返回-1, 错误原因存于errno
 * 函数说明:
 *        截取指定原文件
 * ***************************/
int truncate(const char *path, off_t length);
#include <unistd.h>
#include <sys/types.h>

/*****************************
 * 函数名称:ftruncate
 * 函数入口:
 *             fd   文件句柄
 *             length 指定文件剩余大小
 * 函数出口:
 *       执行成功则返回0, 失败返回-1, 错误原因存于errno
 * 函数说明:
 *        截取指定原文件
 * ***************************/
    int ftruncate(int fd, off_t length);

二者错误代码 errno
1 EACCESS 参数path所指定的文件无法存取 
2 EROFS 欲写入的文件存在于只读文件系统内 
3 EFAULT 参数path指针超出可存取空间 
4 EINVAL 参数path包含不合法字符 
5 ENAMETOOLONG 参数path太长 
6 ENOTDIR 参数path路径并非一目录 
7 EISDIR 参数path指向一目录 
8 ETXTBUSY 参数path所指的文件为共享程序,而且正被执行中 
9 ELOOP 参数path 有过多符号连接问题。 
10 EIO I/O存取错误

示例代码

示例1:fread遇到\0将会停止向下读取?

#include "stdio.h"
#include "string.h"
int main(void)
{
  FILE *fp;
  int a=0;
  int c=0;
  int i=0;
  int j=0;
  char buf[]="$GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,,0000*1F$GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,, NULL";
  char buffer [1024];
  fp = fopen("test.txt", "w+");
  fwrite(buf,strlen(buf)+1,1,fp);//文档末尾写入加入\0
  fclose(fp);
  fp = fopen("test.txt", "a+");//在文件末尾续写
  fputs("123456",fp);
  fclose(fp);
  fp = fopen("test.txt", "r");
  while(1)//判断结束符逐个读取法
  {
    c=fgetc(fp);
    if(feof(fp))
    {
      break;
    }
    a++;
    fputc(c,stdout);
  }
  printf("\r\n");
  printf("%d\r\n",a);
  fclose(fp);
  fp = fopen("test.txt", "r");//使用其他方法读取
  fread(buffer,1024,1,fp);
 // fputs(buffer,stdout);
 while(1)
 {
    printf("%c",buffer[i++]);
    if(i==(sizeof(buf)+strlen((char*)"123456"))+1)//最后一个字符未知字符验证fputs不会再末尾自动加\0
    {
        break;
    }
 }
  printf("\r\n");
  fclose(fp);
  return(0);
}

运行结果:
G P G G A , 092204.999 , 4250.5589 , S , 14718.5084 , E , 2 , 04 , 24.4 , 19.7 , M , , , , 0000 ∗ 1 F GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,,0000*1F GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,,00001FGPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M, NULL123456
145
G P G G A , 092204.999 , 4250.5589 , S , 14718.5084 , E , 2 , 04 , 24.4 , 19.7 , M , , , , 0000 ∗ 1 F GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,,0000*1F GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,,00001FGPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M, NULL123456T
运行结果分析:
使用fgetc结合feof逐个读取将会读全,由于fputs不会再末尾添加字符串结束符\0,因此打印了未知字符“T”通过使用单个字符打印验证了fread读了全部字符,但是其中包括了字符串结束符,如果使用以下代码打印将会得到字符串结束符\0在NULL后

 while(1)
 {
    printf("[%d]:%c\r\n",i++,buffer[i]);
    if(i==(sizeof(buf)+strlen((char*)"123456"))+1)
    {
        break;
    }
 }

示例2:判断文件大小

#include "stdio.h"
#include "string.h"
int main(void)
{
  char buf[]="$GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,,0000*1F$GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,, NULL";
  printf("string size:%ld--%ld\r\n",sizeof(buf),strlen(buf));//前者包括\0后者将不包括\0
  FILE *fp=fopen("./test.txt","w+");
  //fwrite(buf,strlen(buf)+1,1,fp);//此处向文件写入了\0文件大小与sizeof大小相同
  fwrite(buf,strlen(buf),1,fp);//未写入\0文件大小与strlen大小相同
  fseek(fp,0,SEEK_END);//将文件指针偏移到文件末
  printf("file size:%ld\r\n",ftell(fp));
  fclose(fp);
  return(0);
}

运行结果:
写入方式1结果:
string size:139–138
file size:139
写入方式2结果:
string size:139–138
file size:138
运行结果分析:
使用fseek偏移与ftell结合可获取文件实际大小,同时文件属性中实际占用大小也是对应写入方式大小。

示例3:fscanf从标准输入流读入

#include "stdio.h"
int main(void)
{
  /*********测试1:从标准输入流读出************/
  int a=0,b=0;
  char buf[1024]={0};
  fscanf(stdin,"%d:%d:%s",&a,&b,buf);//必须按照对应的格式从标准输入流输入内容
  printf("%d:%02d:%s\r\n",a,b,buf);
}

运行结果:
输入:2022:02:04
输出:2022:02:04

示例4:fscanf从标准输入流读入

#include "stdio.h"
#include "string.h"
int main(void)
{
    char buf[]="Hello today is";
    char buffer1[10]={0};
    char buffer2[10]={0};
    char buffer3[10]={0};
    FILE *fp=fopen("./test.txt","w+");
    fwrite(buf,strlen(buf)+1,1,fp);
    rewind(fp);
    fscanf(fp,"%s %s %s",buffer1,buffer2,buffer3);
    printf("%ld--%s\r\n",strlen(buffer1),buffer1);
    printf("%ld--%s\r\n",strlen(buffer2),buffer2);
    printf("%ld--%s\r\n",strlen(buffer3),buffer3);
    fclose(fp);
}

运行结果:
5–Hello
5–today
2–is

示例5:fscanf正则表达式测试

#include "stdio.h"
#include "string.h"
int main(void)
{
    char buf[]="Hello,today is";
    char buffer1[10]={0};
    char buffer2[10]={0};
    char buffer3[10]={0};
    FILE *fp=fopen("./test.txt","w+");
    fwrite(buf,strlen(buf)+1,1,fp);
    rewind(fp);
    fscanf(fp,"%[^,],%s %s",buffer1,buffer2,buffer3);
    printf("%ld--%s\r\n",strlen(buffer1),buffer1);
    printf("%ld--%s\r\n",strlen(buffer2),buffer2);
    printf("%ld--%s\r\n",strlen(buffer3),buffer3);
    fclose(fp);
}

运行结果:
5–Hello
5–today
2–is

示例6 fprintf使用

#include "stdio.h"
void mian(void)
{
    char buffer1[10]="1987";
    char buffer2[10]="10";
    char buffer3[10]="10";
    char strbuf[30]={0};
    FILE *fp=fopen("./test.txt","w+");
    fprintf(fp,"%s-%s-%s",buffer1,buffer2,buffer3);
    rewind(fp);
    fread(strbuf,strlen(buffer1)+strlen(buffer2)+strlen(buffer3)+3,1,fp);
    puts(strbuf);
    fclose(fp);
}

运行结果:
1987-10-10s

示例7 fgetpos及fsetpos使用

#include "stdio.h"
#include "string.h"
void main(void)
{
    fpos_t postion;
    char buffer1[10] = "1987";
    char buffer2[10] = "10";
    char buffer3[10] = "10";
    char strbuf[30] = {0};
    FILE *fp = fopen("./test.txt", "w+");
    fgetpos(fp, &postion);//获取当前文件流的位置
    printf("%ld\r\n", postion.__pos);
	fprintf(fp, "%s-%s-%s", buffer1, buffer2, buffer3);
	//postion.__pos=2;//可以结构体变量进行赋值再设置文件流的位置
    fsetpos(fp,&postion);//设置文件流的位置
    fread(strbuf, strlen(buffer1) + strlen(buffer2) + strlen(buffer3) + 3, 1, fp);
    puts(strbuf);
    fclose(fp);
}

运行结果:
0
1987-10-10

示例8 truncate使用

#include "stdio.h"
#include "string.h"
#include "unistd.h"
#include "sys/types.h"
void main(void)
{    
int c=0;
    char buf[]="$GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,,0000*1F$GPGGA,092204.999,4250.5589,S,14718.5084,E,2,04,24.4,19.7,M,,,, NULL";
    char buffer[512]={0};
    FILE *fp = fopen("./test.txt", "wb+");
    fputs(buf,fp);
    fclose(fp);
    int ret=truncate("./test.txt", 10);//将会截取文件前10字节后面将会被删除
    printf("%d\r\n",ret);
    perror("truncate");
    fp = fopen("./test.txt", "r+");
    while(1)
    {
        c=getc(fp);
        if(feof(fp))
        {
            break;
        }
        printf("%c",c);
    }
    fclose(fp);
}

运行结果:
0
truncate: Success
$GPGGA,092

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值