文件就是实现数据存储的载体,按数据的组织形式分为:字符文件(文本文件),二进制文件;按照用途分为系统文件,库文件(标准库文件/非标准库文件),用户文件。
Linux下的文件分类:-:普通文件;
d:目录文件/文件夹;
s:套接字文件;
p:管道文件;
l(小写的 L):链接文件;
c:字符设备文件;
b:块设备文件;
man手册:man 1 一般是指令
man 2 一般是系统相关函数
man 3 一般是 C 语言标准库函数
和文件操作相关的流程:第一步打开文件,仅仅得到一个文件描述符;
第二步写/读,用函数操作文件描述符;
第三步关闭文件;
注:我们在使用文件相关函数读写时,要分析一下光标的位置,防止读写文件时出现错误
1.打开和关闭文件
①打开文件:fopen
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
形参:pathname: 路径下的文件名
mode: 打开文件的模式
“r”,只读的方式打开,光标在文件开头,文件不存在,打开失败!
“r+”,读写的方式打开,光标在文件开头,文件不存在,打开失败!
“w”,只写的方式打开,光标在文件开头,文件不存在,创建并打开,文件存在,清空写!
“w+”,读写的方式打开,光标在文件开头,文件不存在,创建并打开,文件存在,清空写!
“a”,追加写,光标在文件末尾,文件如果不存在,创建并打开;
“a+”,可读可写,根据你第一次操作该文件来确定光标位置,第一次如果是读,光标默认在文件开头,第一次如果是写,光标在文件末尾(追加写);
返回值:成功返回FILE *类型的文件描述符;失败返回NULL;
②perror --> 打印失败信息
#include <stdio.h>
void perror(const char *s);
形参:s:提供一个字符串即可(一般写距离最近的函数名)
功能:打印距离他最近的函数执行失败的原因;
③关闭文件:fclose
#include <stdio.h>
int fclose(FILE *stream);
形参: stream,用 fopen 打开文件得到的文件描述符
返回值:成功返回0,失败返回-1;
#include <stdio.h>
int main()
{
FILE *fp=fopen("1.txt","r+");
if(fp==NULL)
{
perror("fopen错误原因:");//打印上方离perror最近的函数的错误原因
return 0;
}
fclose(fp);
return 0;
}
2.单字符读写
①单字符的写: fputc
#include <stdio.h>
int fputc(int c, FILE *stream);
形参:c,传 char 类型的单字符,将字符c写到文件指针fp所指向的文件的当前写指针的位置
Stream,文件描述符
返回值: 成功返回你写入的单字符;失败返回-1
#include <stdio.h>
//fputc单字符的写
int main()
{
FILE *fp=fopen("1.txt","w+");//打开或创建一个1.txt文件,打开时清空
if(fp==NULL)
{
perror("fopen错误原因:");//打印上方离perror最近的函数的错误原因
return 0;
}
char z=0;
printf("输入一个字符\n");
scanf("%c",&z);
fputc(z,fp);
fclose(fp);//关闭文件
return 0;
}
②单字符的读:fgetc
#include <stdio.h>
int fgetc(FILE *stream);
形参:stream,文件描述符
返回值:成功,读取到的单字符,用char类型来承接;失败/读到文件末尾返回:-1
#include <stdio.h>
/*
fgetc单字符的读
*/
int main()
{
FILE *fp=fopen("1.txt","r+");
if(fp==NULL)
{
perror("fopen错误原因:");//打印上方离perror最近的函数的错误原因
return 0;
}
char z=0;
z=fgetc(fp);
printf("读取到的z=%c\n",z);
z=fgetc(fp);
printf("读取到的z=%c=",z);
printf("转换后z=%d\n",z);
fclose(fp);
return 0;
}
3.字符串的读写
①字符串的写:fputs
int fputs(const char *s, FILE *stream);
形参:s:要写入文件中的字符串的首地址
stream:fopen的返回值;
返回值:成功,返回一个非负数,通常为1,失败返回-1
#include <stdio.h>
/*
fputs 字符串的写
成功返回一个非负数(通常为1),失败返回-1
*/
int main()
{
FILE *fp=fopen("2.txt","w+");
if(fp==NULL)
{
perror("fopen错误原因:");//打印上方离perror最近的函数的错误原因
return 0;
}
char w_buf[32]={0};
printf("输入一个字符串\n");
scanf("%s",w_buf);
getchar();
//fputs(w_buf,fp);//fputs("hello",fp);
int res=fputs(w_buf,fp);
printf("res=%d\n",res);//成功返回非负数
fclose(fp);
return 0;
}
②字符串的读:fgets
char *fgets(char *s,int size,FILE *stream);
形参:s: 读取到的内容存放的位置的首地址;
size:要读多大字节!
stream:fopen 的返回值;
返回值:成功,char *s;失败,NULL;
#include <stdio.h>
/*
fgets 字符串的读取
成功返回char *s,失败返回NULL
*/
int main()
{
FILE *fp=fopen("2.txt","w+");
if(fp==NULL)
{
perror("fopen错误原因:");//打印上方离perror最近的函数的错误原因
return 0;
}
char w_buf[32]={0};
char r_buf[10]={0};
printf("输入一个字符串\n");
scanf("%s",w_buf);
getchar();
fputs(w_buf,fp);
rewind(fp);//光标返回到开头
fgets(r_buf,10,fp);
printf("字符串r_buf=%s\n",r_buf);
fclose(fp);
return 0;
}
3.格式化读写
①格式化写入: fprintf
fprintf(fp,“原样输出+格式控制符”,输出列表);
用 fprintf 来实现 printf 的功能:
fprintf(stdout,“hello\n”); == printf(“hello\n”);
②格式化读取: fscanf
int fscanf(FILE *stream, const char *format, ...);
fscanf从文件中读,要求格式和fprintf写入时一模一样;
例:int a=10,b=20,c=30;
fprintf(fp,”%d-%d-%d\n”,a,b,c);
int x,y,z;
fscanf(fp,”%d-%d-%d\n”,&x,&y,&z);
4.块读块写
将文件转化为二进制,二者配合使用;
#include <stdio.h>
/*
fwrite块写 fread块读(转换成 二进制)
配合使用
*/
int main()
{
int num=100;
FILE *fp=fopen("2.txt","w+");
if(fp==NULL)
{
perror("fopen错误原因:");
return -1;
}
int res=fwrite(&num,4,1,fp);
printf("res=%d",res);
return 0;
}
①块写:fwrite
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
形参:ptr: 要写入的内容的首地址
size: 一次写多大
nmemb: 写几次
stream: fopen 的返回值;
返回值:真正写入的次数
②块读:fread
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
形参:ptr: 读取到的内容存放的位置的首地址
size: 一次读多大
nmemb: 读几次
stream: fopen 的返回值;
返回值:成功,真正读取到的次数,遇到文件末尾,返回 0;失败,返回0。
5.光标偏移函数
①fseek:
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
形参:stream: 文件描述符
offset: 偏移量
+往文件末尾方向
-往文件开头方向
whence: 相对位置
SEEK_SET 文件开头
SEEK_CUR 当前位置
SEEK_END 文件末尾
例:fseek(fp,0,SEEK_SET); == rewind(fp); //以文件开头为起始位置,偏移 0 字节
②ftell:
计算光标当前位置距离文件开头的偏移量
#include <stdio.h>
long ftell(FILE *stream);
形参: stream:文件描述符
返回值:光标当前位置距离文件开头的偏移量
利用代码计算文件的大小:
fseek(fp,0,SEEK_END); //光标达到文件末尾
long num = ftell(fp); //num 就是文件大小
③rewind
#include <stdio.h>
void rewind(FILE *stream);
功能:重置文件位置指针到文件开头
返回值:无
#include <stdio.h>
//rewind光标偏移
int main()
{
FILE *fp=fopen("1.txt","w+");
if(fp==NULL)
{
perror("fopen错误原因:");//打印上方离perror最近的函数的错误原因
return 0;
}
char z=0;
printf("输入一个字符\n");
scanf("%c",&z);
fputc(z,fp);
fclose(fp);
return 0;
}
④feof
int feof(FILE *stream);
形参:文件描述符
返回值:如果文件结束,则返回非0值,否则返回0(即,文件结束:返回非0值;文件未结束:返回0值)