1、文件的打开与关闭
- 标准IO打开文件:
open返回的是一个整数 ,称为文件描述符
fopen返回的是一个指针 ,称为文件指针
- 标准IO关闭文件:
注:fclose函数涉及内存释放,不可对同一个文件多次关闭。
#include <stdio.h>
#include <errno.h>
int main(int argc,char *argv[])
{
FILE *fd=fopen("1.txt","r+"); // 以可读可写的方式打开文件,且要求文件必须存在
if (fd==NULL)
{
perror("on fopen\n");
}
else
printf("fopen\n");
fclose(fd); // 关闭文件指针,并释放文件所关联的缓冲区内存
return 0;
}
2、文件内容的读写操作
标准IO跟系统IO不同的地方在于,标准IO的读写操作提供了很多不同的函数接口,以满足不同的需求:
- 按字节读取:
注:
- fgetc()与getc()作用一样,只是fgetc()是函数,getc()是个宏
- fputc()与putc()作用一样,只是fputc()是函数,putc()是个宏
- fgetchar()与getchar()只能从键盘接收数据与在屏幕上输出,不能指定文件;
#include <stdio.h>
#include <errno.h>
int main(int argc,char *argv[])
{
FILE *fd=fopen("1.txt","r+"); // 以可读可写的方式打开文件,且要求文件必须存在
if (fd==NULL)
{
perror("on fopen\n");
}
while(1)
{
int rt=fgetc(fd); //从fd中读取字符
if (rt==EOF)
{
break;
}
putchar(rt); //将rt得到的字符显示到屏幕
}
fclose(fd); // 关闭文件指针,并释放文件所关联的缓冲区内存
return 0;
}
3、按行读写文件
注:
- 对于读操作而言,返回 EOF 意味着读操作失败,这有两种情况:
- 如果 feof(fp) 为真,此时意味着读到了文件末尾,没有数据可读了;
-
如果 ferror(fp) 为真,此时意味着遇到了错误;
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc,char *argv[])
{
FILE *fd=fopen("1.txt","r+"); // 以可读可写的方式打开文件,且要求文件必须存在
if (fd==NULL)
{
perror("on fopen\n");
}
char *buf=calloc(1,20);
while(1)
{
//int rt=fgetc(fd); //按字符从fd中读取数据
fgets(buf,sizeof buf,fd); //按行读取fd的数据
if (feof(fd)) //文件读到最后则成立
{
printf("文件读取完毕\n");
break;
}
printf("%s",buf);
//putchar(rt); //将rt得到的字符显示到屏幕
}
free(buf);
fclose(fd); // 关闭文件指针,并释放文件所关联的缓冲区内存
return 0;
}
fgets() 和 gets() 都是按行读取文件数据,他们的区别是:
- fgets() 可以读取指定的任意文件,而 gets() 只能从键盘读取。
- fgets() 有内存边界判断,而 gets() 没有,因此后者是不安全的,不建议使用。
- fgets() 在任何情形下都按原样读取数据,但 gets() 会自动去除数据末尾的 ‘\n’
fputs() 和 puts() 都是按行将数据写入文件,他们的区别是:
- fputs() 可以将数据写入指定的任意文件,而 puts() 只能将数据输出到屏幕。
- fputs() 在任何情形下都按原样写入数据,但 puts() 会自动给写入数据的末尾加上 ‘\n’
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc,char *argv[])
{
FILE *fd=fopen("1.txt","r+"); // 以可读可写的方式打开文件,且要求文件必须存在
if (fd==NULL)
{
perror("on fopen\n");
}
char *buf=calloc(1,20);
while(1)
{
fgets(buf,sizeof buf,fd); //按行读取fd的数据
if (feof(fd)) //文件读到最后则成立
{
printf("文件读取完毕\n");
break;
}
}
fputs("good",fd); //将good写入fd文件的光标处
free(buf);
fclose(fd); // 关闭文件指针,并释放文件所关联的缓冲区内存
return 0;
}
4、按指定格式读写文件
- fprintf()不仅可以像printf()向设备输出数据,还可以指定文件写入数据;
// 将数据按格式输出到文件指针 fp 所指定的文件中去
fprintf(fd,"%d%f%s",520,13.14,"love");
// 将数据按格式输出到屏幕(即文件指针stdout所指向的文件)
printf( "%d%f%s", 100, 3.14, "abc");
fprintf(stdout, "%d%f%s", 100, 3.14, "abc");
- snprintf()与sprintf()都可以向指定的缓冲区写入数据,但是snprintf()能指定缓冲区大小,所以更安全,优先选择snprintf();
snprintf(buf,10,"%s/%s",inc,jcc); //如果inc为文件,则表示将inc/jcc这个新的路径存入buf中;
- fscanf( )不仅可以像scanf( )一样从标准输入设备读入信息,也可以从由stream指定的任何有相应权限的文件读入数据。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc,char *argv[])
{
FILE *fd=fopen("1.txt","r+"); // 以可读可写的方式打开文件,且要求文件必须存在
if (fd==NULL)
{
perror("on fopen\n");
}
char buf[10];
//fgets(buf,sizeof buf,fd); //按行读取fd的数据
fscanf(fd,"%s",buf); //按字符串读取
printf("%s\n",buf);
fclose(fd); // 关闭文件指针,并释放文件所关联的缓冲区内存
return 0;
}
fscanf
函数在读取字符串时,会一直读取字符直到遇到空格、制表符(tab)或换行符。所以,fscanf(fd,"%s",buf)
一次能从fd
文件中读入的字符数取决于遇到的这些分隔符的位置。如果没有这些分隔符,它会一直读取到缓冲区buf
的大小或者文件结束。
5、按数据块格式读写文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <errno.h>
int main(int argc,char *argv[])
{
FILE *fd=fopen("1.txt","r+"); // 以可读可写的方式打开文件,且要求文件必须存在
if (fd==NULL)
{
perror("on fopen\n");
}
char buf[20];
while(1)
{
bzero(buf,sizeof buf);
int d=fread(buf,sizeof(buf),1,fd); 从文件 fp 中读取1块连续的数据,每块20个字节
if (d<1)
{
printf("%s\n",buf);
break;
}
printf("%s\n",buf);
}
fclose(fd); // 关闭文件指针,并释放文件所关联的缓冲区内存
return 0;
}
6、文件的位置与获取