3.读写函数:
读写函数:
三类读写函数:
一类:行缓存 遇到新行符(\n) 或写满缓存时,即调用系统调用函数
读:fgets, gets, printf, fprintf,sprintf
写:fputs, puts,scanf
一个字符的读写,是否是行缓存?也是行缓存
读:fgetc, getc, getchar
写:fputc, putc,putchar
二类:无缓存 只要用户调这个函数,就会将其内容写到内核中
三类:全缓存 只有写满缓存再调用系统调用函数
3.1 行缓存的读写函数fgets和fputs
int fputs(const char *s,FILE *stream);
第一个参数:缓存,即写什么内容
第二个参数:写到哪里去
若成功则返回非负值,若出错则为EOF(EOF为宏,等价为-1)。
char *fgets (char *s, int size, FILE *stream)
第一个参数:缓存,即读到哪里去
第二个参数:读多少个字节
第三个参数:从什么地方读
返回值若成功则为s(缓存的地址),若已处文件尾端或出错则为null
注意和文件IO进行区别,区别就是将文件IO的第一个参数,调到了最后,就成了标准IO的参数。
例子:
#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello zengzhi\n";
fp=fopen("./a.c","w+");//w a +
if(fp==NULL)
{
printf("open file a.c fail\n");
return -1;
}
printf("cread file a.c suceess\n");
fputs(buf,fp);
fclose(fp);
return 0;
}
运行结果:
关于fgets()函数的例子:
#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello zengzhi\n";
char readbuf[128]={0};
fp=fopen("./a.c","w+");//w a +
if(fp==NULL)
{
printf("open file a.c fail\n");
return -1;
}
printf("cread file a.c suceess\n");
fputs(buf,fp);
//start read
fgets(readbuf,128,fp);
printf("readbuf:%s\n",readbuf);
fclose(fp);
return 0;
}
运行结果:
为什么会读不到数据?和文件IO中的读写指针同理,在库函数缓存里依然需要调整读写指针的位置。这就需要引入读写位置指针函数fseek().
用法和lseek 函数一样,记得用这个函数的时候不要遗漏参数。
int fseek (FILE *__stream, long int __off, int __whence)
功能:调整读写的位置指针;
第一个参数:要调整的文件的文件描述符;
第二个参数:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向后移,向前移);
第三个参数:当前位置的基点,有三个标志,
SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小;
SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。
SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。函
数的
fseek() 参数与lseek是一样的但是返回值不一样
lseek的返回值是:当前文件的位置指针值;
fseek()的返回值是:成功返回0,失败返回-1
#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello zengzhi\n";
char readbuf[128]={0};
fp=fopen("./a.c","w+");//w a +
if(fp==NULL)
{
printf("open file a.c fail\n");
return -1;
}
printf("cread file a.c suceess\n");
fputs(buf,fp);
//start read
fseek(fp,0,SEEK_SET);
fgets(readbuf,128,fp);
printf("readbuf:%s",readbuf);
fclose(fp);
return 0;
}
运行结果:
同时可以用rewind()函数进行调整
rewind(FILE *fp) 用于设定流的文件位置指示为文件开始,该函数调用成功无返回值。
rewind()等价于(void) fseek(fp 0, SEEK_SET)。
ftell(FILE *fp)
用于取得当前的文件位置,调用成功则为当前文件位置指示,若出错则为-1;
#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello zengzhi\n";
char readbuf[128]={0};
fp=fopen("./a.c","w+");//w a +
if(fp==NULL)
{
printf("open file a.c fail\n");
return -1;
}
printf("cread file a.c suceess\n");
fputs(buf,fp);
//start read
// fseek(fp,0,SEEK_SET);
rewind(fp);
fgets(readbuf,128,fp);
printf("readbuf:%s",readbuf);
fclose(fp);
return 0;
}
运行结果:
来测试fputs是不是行缓存:先去掉/n,看是不是能从库缓存写入内核缓存:
#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello zengzhi\n";
char readbuf[128]={0};
fp=fopen("./a.c","w+");//w a +
if(fp==NULL)
{
printf("open file a.c fail\n");
return -1;
}
printf("cread file a.c suceess\n");
fputs(buf,fp);
//start read
fseek(fp,0,SEEK_SET);
fgets(readbuf,128,fp);
printf("readbuf:%s",readbuf);
fclose(fp);
return 0;
}
运行结果:
发现依然可以,为什么,这是因为在使用fclose()关闭文件时,会强制数据从库缓存写入内核缓存。
当在fclose()关闭文件前加入死循环,不让其进行关闭操作时,此时就不能写入。默认情况下是可以关闭的
#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello zengzhi";
fp=fopen("./a.c","w+");//w a +
if(fp==NULL)
{
printf("open file a.c fail\n");
return -1;
}
printf("cread file a.c suceess\n");
fputs(buf,fp);
while(1);
fclose(fp);
return 0;
}
运行结果:
3.2 刷新缓存函数:fflush(FILE *fp)
把库函数中的缓存的内容强制写到内核中。
例子:
#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>
int main(int argc,char *argv[])
{
FILE *fp;
char buf[]="hello zengzhi";
fp=fopen("./a.c","w+");//w a +
if(fp==NULL)
{
printf("open file a.c fail\n");
return -1;
}
printf("cread file a.c suceess\n");
fputs(buf,fp);
fflush(fp);
while(1);
fclose(fp);
return 0;
}
运行结果:
fclose()含有fflush()
3.3 无缓存:stderr
stuout 是行缓存,因为没有\n,所以不输出。
#include <stdio.h>
int main(int argc,char *argv[])
{
printf("hello linux");//stdout
while(1);
return 0;
}
#include <stdio.h>
int main(int argc,char *argv[])
{
// printf("hello linux");//stdout
fputs("hello linux",stdout);
while(1);
return 0;
}
运行结果:
`
加入\n可以显示,或者使用fflush()进行刷新。
#include <stdio.h>
int main(int argc,char *argv[])
{
// printf("hello linux\n");//stdout
fputs("hello linux",stdout);
while(1);
return 0;
}
#include <stdio.h>
int main(int argc,char *argv[])
{
// printf("hello linux");//stdout
fputs("hello linux",stdout);
fflush(stdout);
while(1);
return 0;
}
而stderr为无缓存,可以直接显示
#include <stdio.h>
int main(int argc,char *argv[])
{
// printf("hello linux");//stdout
fputs("hello linux",stderr);
// fflush(stdout)
while(1);
return 0;
}
运行结果: