当前位置: 首页 > news >正文

LinuxC语言文件i/o笔记(第十七天)

最近忙着比赛和学单片机了,原本想着不写博客了,但是发现不自己写一下相关的笔记,有点记不住这些东西,就还是抽时间写了。

标准i/o:

流的打开和关闭:

c语言和c++语言一致,也有关于文件的操作函数,也同要包含标准输入流什么的。

打开流:

在c语言中,我们通过 fopen 关键字打开标准i/o流:

FILE *fopen(const char *path,const char *mode);

        第一个参数是文件名/地址,第二个参数为打开方式,分为六种:"r"、"r+"、"w"、"w+"、"a"、"a+",如果要打开二进制文件就在模式后面加个b,如"rb"。其中,w为只读,w+为读写,它们都要求文件存在,不然会错误;w为只写,w+为读写,它们如果没有文件会创建文件,若存在文件,则清空该文件 ;a和a+和w一致,但是是从文件末端写入数据,而且不清空原文件。
函数成功的话会返回流指针,否侧返回NULL。

#include <stdio.h>......FILE *fpsif((fps = fopen(argv[1],"r")) == NULL){perror("fopen src file");return -1;}......

fopen()函数创建的文件默认权限为0666(rw-rw-rw-)

处理错误信息:

extern int errno
errno为全局变量,存放错误的编号,错误1为无权限,11为无资源等;

void perror(const char *s);
可以打印错误信息,会先输出参数s,在输出errno的错误信息。

char *strerror(int errno);
可以根据错误号返回对应的错误信息,需要头文件<errno.h>,使用起来比上面的麻烦很多。

关闭流:

通过 fclose 关键字关闭标准i/o流:

int fclose(FILE *stream);

成功关闭会返回0,失败返回EOF,并自动设置errno。
关闭时会自动把缓冲区数据写入并释放缓冲区。
虽然程序结束后会自动关闭流,但为了规范和防止出问题,还是要记得写fclose。

按字符输入输出:

c语言有三种输入输出方式,第一个就是按字符输入输出:

int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar(void);

成功时会返回读取到的字符,到文件末尾或出错就会返回EOF。
getchar()是从标准输入流(即终端)获取一个字符。前两个函数当FILE *stream = stdin时,等同于getchar(),stdin就是终端标准流。

输出也有三个函数:

int fputc(int c,FILE *stream);
int putc(int c,FILE *stream);
int putchar(void);

成功的话返回写入的字符,出错返回EOF
putchar()等同于fputc(c,stdout),stdout为标准输出流(即终端)。

#include <stdio.h>int main(int argc,char *argv[]){FILE *fps,*fpd;int ch;if(argc < 3){printf("Usage : %s <sre_file> <dst_file>\n",argv[0]);return -1;}if((fps = fopen(argv[1],"r")) == NULL){perror("fopen src file");return -1;}if((fpd = fopen(argv[2],"w")) == NULL){perror("fopen src file");return -1;}while((ch = fgetc(fps)) != EOF){fputc(ch,fpd);}fclose(fps);fclose(fpd);return 0;
}

使用程序的时候要附带输入输出的文件:

./test text textcp

前者必须存在,因为用的是r只读模式,后者可以不存在,w模式若不存在文件会自动创建一个。

按行输入输出:

不好用!不好用!不好用!
使用不当会导致缓冲区溢出等。
输入函数为:

char *gets(char *a);
char *fget(char *a,int size,FILE *stream);

gets主要用于在标准输入读取一行,和c++的getline很像,但只指定了缓冲区的头地址,而无长度,就容易缓冲区溢出。
fget是从指定流中读取一行写入缓冲区,是指定大小,指定流的读取。
成功的话返回写入的缓冲区a,到末尾或出错时返回NULL。
遇到"\n"或已读取了size-1个字符时返回,末尾会自动加'\0'表示其为字符串。
其中a为char *a[],即字符串,c语言中是没有string的,所以只能使用字符数组。

输出函数和输入函数类似:

int puts(const char *a);
int fputs(const char *a,FILE *stream);

成功的话返回写入的流的字符个数,到末尾或出错时返回EOF。
puts将a输入到stdout时会追加'\n',fputs不会追加换行符。

按对象输入输出:

size_t fread(void *prt,size_t size,size_t n,FILE *fp);
size_t fwrite(const void *prt,size_t size,size_t n,FILE *fp);

数据文件为整数,就可以以整型对象去读取,若为字符,就以以字符对象读取。
prt为缓冲区,要自己先定义好,size为每个对象的大小,字符为1字节,整型为4字节,n为读取输出的对象长度,fp为输入输出流。
成功返回实际读写的对象个数,出错返回EOF。

#include <stdio.h>
#define N 64
int main(int argc ,char *argv[]){FILE *fps,*fpd;char buf[N];int n;if(argc < 3){printf("Usage : %s <sre_file> <dst_file>\n",argv[0]);return -1;}if((fps = fopen(argv[1],"r")) == NULL){perror("fopen src file");return -1;}if((fpd = fopen(argv[2],"w")) == NULL){perror("fopen src file");return -1;}while((n = fread(buf,1,N,fps)) > 0){fwrite(buf,1,n,fpd);}fclose(fps);fclose(fpd);return 0;
}

fgetc/fputc 效率低但安全
fgets/fputs 效率较高,但是不安全,而且只能文本读写
fread/fwrite 效率高,安全,可以指定读取,节省内存等

流的相关操作:

刷新流:

int fflush(DILE *fp);

正常程序中,只用关闭流或程序结束的时候,缓冲区的数据才会实际写入文件,但如果遇到要长期运行的程序就会导致数据转移失败或延后,就可以对当前的输入输出流进行刷新,将缓冲区的数据马上写入实际的文件,但Linux系统只能对输出流进行刷新。
成功的时候返回0,失败返回EOF;

定位流:

long ftell(FILE *fp);
long fseek(ILE *fp,long offset,int whence);
long rewind(ILE *fp);

ftell返回的是当前读写的位置,出错返回EOF;
fseek参数为流指针、偏移量和指定位置,指定位置参数为(SEEK_SET(开始位置),SEEK_CUP(当前位置),SEEK_END(文件末尾)),成功返回流,失败为EOF。
rewind就是把文件定位回开头,即fseek(fp,0,SEEK_SET)。

判断流的出错和结束:

上面错误流讲过error函数了,就不再多讲。
判断流是否结束的函数为

int feof(FILE *fp);
返回1表示已到末尾,返回0则未到。

#include <stdio.h>
int main(){FILE *fp;if((fp = fopen("test.txt","r+")) == NULL){perror("fopen");return -1;}fseek(fp,0,SEEK_END);fputc('t',fp);fflush(fp);printf("ftell(fp) = %ld\n", ftell(fp));if(feof(fp) == 1){printf("到达文件末端\n");}fclose(fp);return 0;
}

格式化输出:

在c语言中,我们经常用到printf进行输出,在流里,还有两种:

int fprintf(FILE *FP,const char *fmt,....);
int sprintf(char *a,const char *fmt,...);

和printf一样,fmt为“%d”,time这样把像输入的东西按照%d,%s什么的格式输入进流,fprintf是输入到文件,sprintf为输入到缓冲区里。

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <string.h>
int main(){FILE *fp;int line = 0;char buf[64];time_t t;struct tm *tp;if((fp = fopen("test.txt","a+")) == NULL){perror("fopen");return -1;}while(fgets(buf,64,fp) != NULL){if(buf[strlen(buf) - 1] == '\n') { line++; }}while(1){time(&t);tp = localtime(&t);fprintf(fp,"%02d,%d-%02d-%02d %02d:%02d:%02d\n",++line,tp->tm_year+1900,tp->tm_mon+1,tp->tm_mday,tp->tm_hour,tp->tm_min,tp->tm_sec);fflush(fp);sleep(1);}return 0;
}
http://www.dtcms.com/a/609326.html

相关文章:

  • Spring AI Evaluation Testing(评估测试)
  • 太仓营销型网站建设四平网站建设怎么选
  • 记一次慢接口优化:载体详情页从90秒到800毫秒的性能提升实战
  • 微软Visual Studio 2026正式登场,AI融入开发核心操作体验更流畅
  • 微软vcpkg包管理工具如何使用?
  • 提供小企业网站建设织梦网站默认密码忘记
  • 基于XTOM蓝光扫描的复杂中小尺寸零件3D形貌重建与全尺寸误差分析
  • Qt 自定义菜单栏 / 工具栏按钮 QToolButton + InstantPopup 详细解析
  • 2025年AI生成PPT工具深度评测:技术对比与实战分析
  • 智慧园区:科技赋能下的安全便捷生活新范式
  • 华为WATCH 5:连接心与心,让生活更美好
  • 内容管理系统解决方案架构及实施
  • 建设银行网站的服务管理商业机构的网站是什么
  • Python与大数据:使用PySpark处理海量数据
  • Django 缓存详解与应用方法
  • SDN架构详解
  • Spring Boot缓存实战:@Cacheable注解详解与性能优化
  • LeetCode热题100--17. 电话号码的字母组合
  • C++初阶(07):STL简介
  • 中国哪些网站做软装建设彩票网站合法吗
  • 百度网站评分椒江做网站
  • yolov8目标检测训练在rk3588上部署
  • 学术数据可视化:高效图表工具助力科研数据精准呈现
  • 焦作高端网站建设宁波seo外包服务平台
  • Apple 官方提供 Xcode 周边实用工具集,包含CarPlay 模拟器,网速限制等 Additional Tools for Xcode 26.1,
  • 《隐藏(Hide)》
  • 基于Mask R-CNN的汽车防夹手检测与识别系统
  • 从正向困境到反向破局:详解地下城游戏的动态规划解法
  • 常州新北区网站建设东莞搜索排名提升
  • 专题:2025构建全自动驾驶汽车生态系统:中国智能驾驶行业全景研究报告|附80+份报告PDF、数据仪表盘汇总下载