文件访问
为了读写一个文件,在<stdio.h>中定义了一个结构体,该结构体可能通过typedef声明为FILE,结构体内容为,缓冲区的位置、缓冲区当前字符的位置,文件的读写状态,是否出错或者是否已经达到文件尾部,应该还有一个字符串用来存储文件内容;形如这种
typedef struct
{
int location;//类型待定,可能是基本数据类型也可能是个结构体
int currt_location;
int status;
bool err;
char *file_content;
}FILE;
以上仅限于猜测。不同类型的文件内容也是不同的。
像可重新定位的目标文件,其内容就非常丰富;
ELF头 |
---|
.text |
.rodata |
.data |
.bss |
.symtab |
.rel.text |
.rel.data |
.debug |
.line |
.strtab |
.节头部表 |
.text为已经编译的机器代码。
.rodata只读数据
。。。
.strtab为一个字符串表。
可见对文件内容的定义,不同作用的文件还是有非常大的区别的。
回到主题
定义一个文件指针
FILE *fp;
FILE *fopen(char *name,char *mode);
其中fp为一个指向结构FILE的指针,fopen函数返回指向结构FILE的指针。
fopen的第一个参数是字符串,它包含文件名,第二个参数为访问模式,是一个字符串,允许的模式包括:“r”,“w”,“a”;
int getc(FILE *fp);
getc函数返回fp指向输入流中的下一个字符;如果文件到达尾部或者出错,返回EOF;
int putc(int c,FILE *fp);
函数将字符c写入到fp指向的文件中;并返回输入字符。
启动c程序时,操作系统将打开三个文件,stdin,stdout,stderr;它们在<stdio.h>中声明;
重写getchar()函数
#define getchar() getc(stdin)
#define putchar() putc(©,stdout)
从文件中格式化读取或者格式化写入文件
int fscanf(FILE *fp,char *fmt,…);
int fprintf(FILE *fp,char *fmt,…).
将文件ifp复制到ofp
void filecopy(FILE *ifp,FILE *ofp)
{
int c;
while((c=getc(ifp))!=EOF)
{
putc(c,ofp);
}
}
写cat函数,实现当没有命令行参数时,从stdin输出到stdout。当有命令行参数时,参数将被解释为文件名,并逐个处理
#include <stdio.h>
int main(char *argc,char *argv[])
{
FILE *fp;
if(argc==1)
{
filecopy(stdin,stdout);
}
else
{
while(--argc>0)
{
if((fp=fopen(*++argv,"r"))==NULL)
{
printf("cat:cant open %s\n",*argv);
return 1;
}
else
{
filecopy(fp,stdout);
fclose(fp);
}
}
}
return 0;
}