当前的计算系统除了包括对数据有 加工和处理 以外还有 搬运
这个 搬运 代表着 输入和输出 ,及 input/output ,简称 I/O
UNIX/Linux 的缔造者们将数据的 来源和目标 都抽象为 文件,所以在 UNIX/Linux 系统中 一切皆文件
一切皆文件 不仅仅对磁盘,还包括鼠标,键盘,显示器这些设备,那么对这些设备的操作也都抽象成了对 文件的I/O操作
关于 标准I/O 可以参看前面一篇文章 《标准I/O (一)》 ,关于C语言的API(linux)可以参看 Linux C API 参考手册 在线文档
这里分享一下我在学习 UNIX I/O 库过程中的笔记和心得
下面是一些 标准IO库中的常用函数
File *fopen(const char*path,const char *mode)
int fseek(FILE *stream, long offset, int whence)
long ftell(FILE *stream)
void rewind(FILE *stream)
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
int fclose(FILE *stream)
void *malloc(size_t size)
void free(void *ptr)
给定一个已知文件a(大小确定,文件内容自行用vi输入n个字符),将文件中的内容倒序后存入文件b中。路径都在/home/emacs/file/下
#include <stdio.h> //标准IO库
#include <malloc.h> //动态内存分配函数库
int slen(char *s) //求字符串长度 (string.h中的strlen函数有相同功能)
{
int i=0;
for(;*s!='\0';s++)i++; //使用i进行计数
return i;
}
char * srev(char *s) //字符串翻转(因为没有现成的翻转函数,所以得自己写)
{
int i=0,len=slen(s);
char tmpc='\0'; //之所以将各种变量定义后,同时进行赋值初始化,是为了避免不可知不可控的状况
for(i=0;i<len/2;i++) //从字符串两边往中间依次进行收尾对调
{
tmpc=s[i];
s[i]=s[len-1-i];
s[len-1-i]=tmpc;
}
return s;
}
int main()
{
FILE *fp=NULL,*fb=NULL;
char *fileA="/home/emacs/file/a";
char *fileB="/home/emacs/file/b";
char *tmps=NULL;
long len=0; //进行各种赋值初始化
if(NULL == (fb=fopen(fileB,"w+"))) //以写也可读的方式打开文件B,出错则提醒并退出
{
printf("cannot open file:%s\n",fileB);
return -1;
}
if(NULL == (fp=fopen(fileA,"r+"))) //以读也可写的方式打开文件A,出错则提醒并退出
{
printf("cannot open file:%s\n",fileA);
return -1;
}
fseek(fp,0L,2); //定位到文件末尾
len=ftell(fp); //取出当前的位置偏移量,是为了获取文件长度
if(1 > len) //如果文件为空,就提醒并退出
{
printf("%s is a empty file,please input something\n",fileA);
return -1;
}
rewind(fp); //重新归置文件指针位置到文件开头
if (NULL == (tmps=(char*)malloc(sizeof(char)*(len+1)))) //申请一段长度为len+1个char的空间,出错则提醒并退出
{
printf("no enough memory\n");
return -1;
}
if(1 != fread(tmps,sizeof(char)*len,1,fp)) //从文件A中读取len个char长度的内容写到tmps的临时空间中,出错则提醒并退出
{
printf("file read error:%s\n",fileA);
return -1;
}
tmps[len]='\0'; //将结尾加上字符串结束符,之所以进行这一步,是为了给翻转作准备的,没有'\0'结尾,很可能产生乱码
srev(tmps); //将字符串内容进行翻转
if(1 != fwrite(tmps,sizeof(char)*len,1,fb)) //从tmps的临时空间中读取len个char长度的内容写到文件B中,出错则提醒并退出
{
printf("file write error:%s\n",fileB);
return -1;
}
free(tmps); //释放tmps的临时空间
fclose(fp); //关闭文件A
fclose(fb); //关闭文件B,这步操作可以有效避免缓存未刷新到硬盘的潜在隐患
return 0;
}
Note: 文件打开数是一种系统资源,是有上限的,虽然程序退出后,系统会帮忙清理,但在程序设计中,打开文件,使用完后进行手动关闭是一种很好的习惯,这样可以有效避免缓存未刷新的潜在隐患
emacs@ubuntu:~/c$ alias gtc
alias gtc='gcc -Wall -g -o'
emacs@ubuntu:~/c$ gtc acopytob.x acopytob.c
emacs@ubuntu:~/c$ cat /home/emacs/file/a
1234567890abcdef
emacs@ubuntu:~/c$ cat /home/emacs/file/b
emacs@ubuntu:~/c$ ./acopytob.x
emacs@ubuntu:~/c$ cat /home/emacs/file/a
1234567890abcdef
emacs@ubuntu:~/c$ cat /home/emacs/file/b
fedcba0987654321emacs@ubuntu:~/c$
emacs@ubuntu:~/c$
编译执行过程中没有报错,从结果来看,b文件中的内容变化也符合预期
以下这些函数可以应对绝大部分的IO需求
fopen/fclose
fread/fwrite
fseek/ftell/rewind
通过各方面资料弄懂其参数的意义和返回值的类型,是熟练掌握的基础
原文地址
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有