【C语言--文件】(详细解读)

文件

磁盘上的文件,文件是一种存放数据的媒介
一般在程序设计中,文件分为两种:程序文件和数据文件。

程序文件

.c .h(源程序文件).obj(目标文件).exe(可执行程序文件)类的文件,能够被执行,被编译
程序文件可以操作数据文件

数据文件

可以被操作,是程序运行时读写的数据

文件名

包含三部分:文件路径+文件主干名+文件后缀
eg:c:\user\test.txt

文件类型

数据文件分为:文本文件和二进制文件

文件缓冲区

ANSIC标准采用“缓冲文件系统”处理数据文件,[系统自动在内存中为程序中每一个正在使用的文件开辟一块文件缓冲区]
从内存向磁盘输出数据,会先放在缓冲区,如果缓冲区放满了再一起放入磁盘;从磁盘文件读取数据,会先输入到内存缓冲区,装满缓冲区再逐个送入数据区(缓冲区大小由C编译器决定)
在这里插入图片描述

文件指针

也称“文件类型指针”,在输出数据文件时需要先装满磁盘,所以要有存储数据文件,程序会自动建立一个文件信息区[存放数据文件的相关信息]
文件信息区是用来存放文件相关信息的,这些信息保存在一个结构体类型的变量中,FILE类型,系统中有定义(编译器不同结构体中成员有所差异,不过都是大同小异的),我们要维护相关信息就得定义一个FILE*型的变量(文件指针)
通过文件指针可以找到与它关联的文件
在这里插入图片描述


操作文件

文件的打开和关闭

文件使用之前要打开文件,使用之后要关闭文件
【1】打开文件
使用函数fopen()
FILE* fopen(const char* filename,const char* mode)
参数包括:文件名+打开方式
打开方式包括:
在这里插入图片描述
在这里插入图片描述

写法:
1.相对路径
fopen(“test.txt”,“r”);
//表示在当前路径的同级路径下
…/ 表示上一级路径
fopen(“…/test.txt”,“r”);
//表示在上一级路径下
fopen(“…/…/test.txt”,“r”);
//表示在上上级路径下
2.绝对路径
fopen(“C:\code\store\Project2\test.txt”,“r”);
//通过转义字符读取‘\’
【2】关闭文件
int fclose(FILE* stream)

#include<errno.h>
#include<string.h>
//打开文件
FILE* pf=fopen("test.txt","r");
if(pf==NULL)//可能打开失败返回空指针,用strerror函数打印错误
{
    printf("%s\n",strerror(errno));
    return 0;
}
//打开成功
//读取文件
//关闭文件
fcolse(pf);//传值调用并不会改变pf本身,因此需要另外置空释放空间
pf=NULL;
文件的顺序读写
输入输出的判断

在这里插入图片描述

在这里插入图片描述
注意:
从键盘输入以及输出到屏幕中,屏幕和键盘都是外部设备
键盘———标准输入设备——stdin
屏幕———标准输出设备——stdout
是一个程序默认打开的两个流设备
stdin stdout stderer
这三个流是默认打开的都是FILE*型的

  • 字符输出函数——写字符
    fputc———连接输出流,输出一个字符
FILE* pf=fopen("test.txt","w");
if(pf==NULL)
{
    printf("%s\n",strerror(errno));
    return 0;
}
fputc('b',pf);
fcolse(pf);//传值调用并不会改变pf本身,因此需要另外置空释放空间
pf=NULL;

  • 字符输入函数——读字符
    fgetc——连接输入流,读入一个字符
FILE* pf=fopen("test.txt","r");
if(pf==NULL)
{
    printf("%s\n",strerror(errno));
    return 0;
}
int ch=fgetc(pf);
printf("%c",ch);
fclose(pf);
pf=NULL;
  • 文本行输入函数——读文件
    fgets()函数
    char *fgets(char *string, int n, FILE *stream )
int main()
{
    char arr[100]={0};
    FILE* pf=fopen("test.txt","r");
    if(pf==NULL)
    {
        printf("%s\n",strerror(errno));
        return 0;
    }
    fgets(arr,100,pf);
    printf("%s",arr);//也可以用puts(pf);函数实现输出
    fcolse(pf);
    pf=NULL;
    return 0;
}
  • 文本行输出函数——写文件
    fputs()
    int fputs( const char *string, FILE *stream );
int main()
{
    char arr[100]={0};
    FILE* pf=fopen("test.txt","w");
    if(pf==NULL)
    {
        printf("%s\n",strerror(errno));
        return 0;
    }
    fputs("hello",pf);
    
    fcolse(pf);
    pf=NULL;
    return 0;
}
int main()
{
    char buf[1024]={0};
    fgets(buf,1024,stdin);//从标准输入流读取
    fputs(buf,stdout);//输出到标准输出流
    return 0;
}

这种写法等价于
gets(buf);
puts(buf);

  • 格式化输入函数
    fscanf()函数
    int fscanf( FILE *stream, const char *format [, argument ]… )
    对比int scanf( const char format [,argument]… )
    和scanf使用基本相同,但还需要传递一个FILE
    型的参数

  • 格式化输出函数
    fprintf()
    int fprintf( FILE *stream, const char *format [, argument ]…)
    对比int printf( const char format [, argument]… )
    和printf使用基本相同,但还需要传递一个FILE
    型的参数
    例如:fprintf(pf,“%d %f %s”,10,3.14,“hello”);

  • scanf/printf fscanf/fprintf sscanf/sprintf的区别?
    scanf/printf——针对标准输入/输出流的格式化输入/输出语句
    fscanf/fprintf——针对所有输入/输出流的格式化输入/输出语句
    sscanf/sprintf——从字符串(buffer)中读入到tmp(相同类型结构)/将文件信息转化为字符串(buffer)
    int sscanf( const char *buffer, const char *format [, argument ] … );
    int sprintf( char *buffer, const char *format [, argument] … );

  • 二进制输出
    fwrite()函数
    size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream )
    将buffer中的内容写入stream

  • 二进制输入
    fread()函数
    size_t fread( void *buffer, size_t size, size_t count, FILE *stream )
    将stream中的内容读入buffer

文件的随机读写
  • fseek()函数——根据文件指针的位置和偏移量来定位文件指针
    Moves the file pointer to a specified location.
    int fseek( FILE *stream, long offset, int origin );
    offset—偏移量(单位是字节)
    origin–文件指针位置,分为三种形式:
    SEEK_CUR
    Current position of file pointer
    SEEK_END
    End of file
    SEEK_SET
    Beginning of file
  • ftell()函数
    long ftell( FILE *stream );
    返回文件指针相对于起始位置的偏移量
  • rewind()函数
    void rewind( FILE *stream );
    让文件指针回到起始位置
文本文件和二进制文件

由前面的知识,我们知道数据文件分为:文本文件和二进制文件。两者又有什么区别呢?
主要体现在存储形式上的不同,字符都是以ASCII码的形式存储在内存中;而数字在输出到磁盘时,则可能是以ASCII码值形式,也可能是以二进制形式。如果是以ASCII码值形式输出到磁盘,则称为文本文件;如果是以二进制形式存储到磁盘,则称为二进制文件
举个简单的例子:
int a=10000存储到文件中有两种形式:
在这里插入图片描述

文件结束判定

feof()应用于当文件读取结束了,判断是读取失败结束还是遇到文件尾结束,而不是用来判断文件是否结束的
EOF-end of file(定义中是-1)
文件读取失败perror()函数打印输入的内容++原因
【1】文本文件读取结束判断返回值为EOF(fgetc判断)还是NULL(fgets判断)
【2】二进制文件读取判断返回值是否小于实际要读的个数(fread判断)

if(feof(pf))
	printf("error\n");
else if(ferror(pf))
	printf("file is end\n");
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
简介: C语言是编程语言中的一朵奇葩,虽已垂垂老矣,但却屹立不倒,诞生了数十年,仍然是最流行的编程语言之一。C语言看似简单,却不易吃透,想要运用好,更是需要积淀。本书是一本修炼C程序设计能力的进阶之作,它没有系统地去讲解C语言的语法和编程方法,而是只对C语言中不容易被初学者理解的重点、难点和疑点进行了细致而深入的解读,揭露了C语言中那些鲜为普通开发者所知的秘密,旨在让读者真正掌握C语言,从而编写出更高质量的C程序代码。 全书一共11章:第1章重点阐述了C语言中不易被理解的多个核心概念,很多初学者在理解这些概念时都会存在误区;第2~8章对预处理、选择结构和循环结构的程序设计、数组、指针、数据结构、函数和文件等知识点的核心问题和注意事项进行了讲解;第9章介绍了调试和异常处理的方法及注意事项;第10章对C语言中的若干容易让开发者误解误用的陷阱知识点进行了剖析;第11章则对所有程序员必须掌握的几种算法进行了详细的讲解;附录经验性地总结了如何养成良好的编码习惯,这对所有开发者都尤为重要。 本书主要内容:  堆和栈、全局变量和局部变量、生存期和作用域、内部函数和外部函数、指针变量、指针数组和数组指针、指针函数和函数指针、传址和传值、递归和嵌套、结构体和共用体、枚举、位域等较难理解的核心概念的阐述和对比;  预处理中的疑难知识点,包括文件的包含方式、宏定义及其常见错误解析、条件编译指令和#pragma指令的使用等;  if、switch等选择结构语句的使用注意事项和易错点解析;  for、while、do while等循环结构语句的使用注意事项和易错点解析;  循环结构中break、continue、goto、return、exit的区别;  一维数组、二维数组、多维数组、字符数组、动态数组的定义和引用,以及操作数组时的各种常见错误解析;  不同类型的指针之间的区别,以及指针的一般用法和注意事项;  指针与地址、数组、字符串、函数之间的关系,以及指针与指针之间的关系;  枚举类型的使用及注意事项,结构体变量和共用体变量的初始化方法及引用;  传统链表的实现方法和注意事项,以及对传统链表实现方法的颠覆;  与函数参数、变参函数、函数调用、函数指针相关的一些难理解和容易被理解错的知识点解析;  文件和指针的使用原则、技巧和注意事项;  函数调用和异常处理的注意事项和最佳实践;  与strlen、sizeof、const、volatile、void、void*、#define、typedef、realloc、malloc、calloc等相关的一些陷阱知识点的解析;  时间复杂度、冒泡排序法、选择排序法、快速排序法、归并排序法、顺序排序法、二分查找等常用算法的详细讲解;  良好的编码习惯和编程风格。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伱恏呀呀呀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值