十、文件操作:fopen、fclose、feof;fgetc、fputc、fgets、fputs、fprintf、fscanf、fread、fwrite;fseek、ftell、rewind;stat、remove、rename;文件缓冲区、更新缓冲区fflush

 

复制代码
文件指针;stdin、stdout、stderr;文件操作一般步骤
========================================================================================================
文件指针
在C语言中用一个指针变量指向一个文件,这个指针称为文件指针。 
typedef struct
{
    short           level;    //缓冲区"满"或者"空"的程度 
    unsigned        flags;    //文件状态标志 
    char            fd;        //文件描述符
    unsigned char   hold;    //如无缓冲区不读取字符
    short           bsize;    //缓冲区的大小
    unsigned char   *buffer;//数据缓冲区的位置 
    unsigned        ar;     //指针,当前的指向 
    unsigned        istemp;    //临时文件,指示器
    short           token;    //用于有效性的检查 
}FILE;

FILE是系统使用typedef定义出来的有关文件信息的一种结构体类型,结构中含有文件名、文件状态和文件当前位置等信息。
声明FILE结构体类型的信息包含在头文件“stdio.h”中,一般设置一个指向FILE类型变量的指针变量,然后通过它来引用这些FILE类型变量。通过文件指针就可对它所指的文件进行各种操作。 

-----------------------------------------------------------------
文件指针和普通指针区别:
    FILE *fp = NULL;
    借助文件操作函数来改变 fp 为空、野指针的状况。    fopen();  --> 相当于 fp = malloc();
    操作文件, 使用文件读写函数来完成。 fputc、fgetc、fputs、fgets、fread、fwrite

-----------------------------------------------------------------
C语言中有三个特殊的文件指针由系统默认打开,用户无需定义即可直接使用:
    stdin: 标准输入,默认为当前终端(键盘),我们使用的scanf、getchar函数默认从此终端获得数据。
    stdout:标准输出,默认为当前终端(屏幕),我们使用的printf、puts函数默认输出信息到此终端。
    stderr:标准出错,默认为当前终端(屏幕),我们使用的perror函数默认输出信息到此终端。

-----------------------------------------------------------------
文件操作一般步骤:
    1. 打开文件 fopen()  --》 FILE *fp;
    2. 读写文件 fputc、fgetc、fputs、fgets、fread、fwrite
    3. 关闭文件 fclose()  
文件指针;stdin、stdout、stderr;文件操作一般步骤
复制代码

 

复制代码
文件的打开和关闭:fopen()、fclose()
================================================================================================
#include <stdio.h>
FILE * fopen(const char * filename, const char * mode);
功能:打开文件
参数:
    filename:需要打开的文件名,根据需要加上路径
    mode:打开文件的模式设置
返回值:
    成功:文件指针
    失败:NULL

第一个参数的几种形式:
    FILE *fp_passwd = NULL;

    //相对路径:
    //打开当前目录passdw文件:源文件(源程序)所在目录
    FILE *fp_passwd = fopen("passwd.txt", "r");
    
    //打开当前目录(test)下passwd.txt文件
    fp_passwd = fopen(". / test / passwd.txt", "r");
    
    //打开当前目录上一级目录(相对当前目录)passwd.txt文件
    fp_passwd = fopen(".. / passwd.txt", "r");
        
    //绝对路径:
    //打开C盘test目录下一个叫passwd.txt文件
    fp_passwd = fopen("c:/test/passwd.txt","r");

第二个参数的几种形式(打开文件的方式):
打开模式    含义
r或rb    以只读方式打开一个文本文件(不创建文件,若文件不存在则报错)
w或wb    以写方式打开文件(如果文件存在则清空文件,文件不存在则创建一个文件)
a或ab    以追加方式打开文件,在末尾添加内容,若文件不存在则创建文件
r+或rb+    以可读、可写的方式打开文件(不创建新文件)
w+或wb+    以可读、可写的方式打开文件(如果文件存在则清空文件,文件不存在则创建一个文件)
a+或ab+    以添加方式打开可读、可写的文件。若文件不存在则创建文件;如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留。


注意:
    b是二进制模式的意思,b只是在Windows有效,在Linux用r和rb的结果是一样的
    Unix和Linux下所有的文本文件行都是\n结尾,而Windows所有的文本文件行都是\r\n结尾
    在Windows平台下,以“文本”方式打开文件,不加b:
        当读取文件的时候,系统会将所有的 "\r\n" 转换成 "\n"
        当写入文件的时候,系统会将 "\n" 转换成 "\r\n" 写入 
        以"二进制"方式打开文件,则读写都不会进行这样的转换
    在Unix/Linux平台下,“文本”与“二进制”模式没有区别,"\r\n" 作为两个字符原样输入输出


-----------------------------------------------------------------------------------------------
#include <stdio.h>
int fclose(FILE * stream);
功能:关闭先前fopen()打开的文件。此动作让缓冲区的数据写入文件中,并释放系统所提供的文件资源。
参数:
    stream:文件指针
返回值:
    成功:0
    失败:-1
文件的打开和关闭:fopen()、fclose()
复制代码

 

复制代码
文件结尾;判断是否读取到文件结尾feof()
================================================================================================
文件结尾
在C语言中,EOF表示文件结束符(end of file)。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须是文本文件。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。

#define EOF    (-1)

当把数据以二进制形式存放到文件中时,就会有-1值的出现,因此不能采用EOF作为二进制文件的结束标志。为解决这一个问题,ANSI C提供一个feof函数,用来判断文件是否结束。feof函数既可用以判断二进制文件又可用以判断文本文件。

-----------------------------------------------------------------------------------------------
#include <stdio.h>
int feof(FILE * stream);
功能:检测是否读取到了文件结尾。判断的是最后一次“读操作的内容”,不是当前位置内容(上一个内容)。
参数:
    stream:文件指针
返回值:
    非0值:已经到文件结尾
    0:没有到文件结尾


feof()函数:
    int feof(FILE * stream);
        参1: fopen的返回值
        返回值: 到达文件结尾--》非0【真】
             没到达文件结尾--》0【假】

    作用:    
        用来判断到达文件结尾。 既可以判断文本文件。也可以判断 二进制文件。
    特性:
        要想使用feof()检测文件结束标记,必须在该函数调用之前,使用读文件函数。
        feof()调用之前,必须有读文件函数调用。
文件结尾;判断是否读取到文件结尾feof()
复制代码

 

复制代码
按照字符读写文件fgetc、fputc
================================================================================================
#include <stdio.h>
int fputc(int ch, FILE * stream);
功能:将ch转换为unsigned char后写入stream指定的文件中
参数:
    ch:需要写入文件的字符
    stream:文件指针
返回值:
    成功:成功写入文件的字符
    失败:返回-1

-----------------------------------------------------------------------------------------------
#include <stdio.h>
int fgetc(FILE * stream);
功能:从stream指定的文件中读取一个字符
参数:
    stream:文件指针
返回值:
    成功:返回读取到的字符
    失败:-1
按照字符读写文件fgetc、fputc
复制代码

 

复制代码
按照行读写文件fgets、fputs
================================================================================================
#include <stdio.h>
int fputs(const char * str, FILE * stream);
功能:将str所指定的字符串写入到stream指定的文件中,字符串结束符 '\0'  不写入文件。 
获取一个字符串, 以\n作为结束标记。自动添加 \0. 空间足够大 读\n, 空间不足舍弃\n, 必须有\0。
参数:
    str:字符串
    stream:文件指针
返回值:
    成功:0
    失败:-1

-----------------------------------------------------------------------------------------------
#include <stdio.h>
char * fgets(char * str, int size, FILE * stream);
功能:从stream指定的文件内读入字符,保存到str所指定的内存空间,直到出现换行字符、读到文件结尾或是已读了size - 1个字符为止,最后会自动加上字符 '\0' 作为字符串结束。
写出一个字符串,如果字符串中没有\n, 不会写\n。
参数:
    str:字符串
    size:指定最大读取字符串的长度(size - 1)
    stream:文件指针
返回值:
    成功:成功读取的字符串
    读到文件尾或出错: NULL
按照行读写文件fgets、fputs
复制代码

 

复制代码
按照格式化文件fprintf、fscanf
================================================================================================
#include <stdio.h>
int fprintf(FILE * stream, const char * format, ...);
功能:根据参数format字符串来转换并格式化数据,然后将结果输出到stream指定的文件中,指定出现字符串结束符 '\0'  为止。
参数:
    stream:已经打开的文件
    format:字符串格式,用法和printf()一样
返回值:
    成功:实际写入文件的字符个数
    失败:-1

-----------------------------------------------------------------------------------------------
#include <stdio.h>
int fscanf(FILE * stream, const char * format, ...);
功能:从stream指定的文件读取字符串,并根据参数format字符串来转换并格式化数据。
    1) 边界溢出。 存储读取的数据空间。在使用之前清空。
    2)fscanf函数,每次在调用时都会判断下一次调用是否匹配参数2, 如果不匹配提前结束读文件。(feof(fp) 为真)。
参数:
    stream:已经打开的文件
    format:字符串格式,用法和scanf()一样
返回值:
    成功:参数数目,成功转换的值的个数
    失败: - 1
按照格式化文件fprintf、fscanf
复制代码

 

复制代码
用法对比:printf/sprintf/fprintf;scanf/sscanf/fscanf
===================================================================================================
printf --- sprintf --- fprintf: 
    变参函数:参数形参中 有“...”, 最后一个固参通常是格式描述串(包含格式匹配符), 函数的参数个数、类型、顺序由这个固参决定。
    printf("hello");
    printf("%s", "hello");
    printf("ret = %d+%d\n", 10, 5);
    printf("%d = %d%c%d\n", 10+5, 10, '+', 5);            --> 屏幕
    char buf[1024];   //缓冲区  
    sprintf(buf, "%d = %d%c%d\n", 10+5, 10, '+', 5);        --> buf 中
    FILE * fp = fopen();
    fprintf(fp, "%d = %d%c%d\n", 10+5, 10, '+', 5);            --> fp 对应的文件中

-----------------------------------------------------------------------------------------------
scanf --- sscanf --- fscanf
    scanf("%d", &m);        键盘 --> m
    char str[] = "98";
    sscanf(str, "%d", &m);        str --> m
    FILE * fp = fopen("r");
    fscanf(fp, "%d", &m);        fp指向的文件中 --> m
用法对比:printf/sprintf/fprintf;scanf/sscanf/fscanf
复制代码

fgetc/fputc/fgets/fputs/fprintf/fscanf 默认处理文本文件。
fwrite()/fread()函数: 既可处理以文本文件。也处理二进制文件。

 

复制代码
按照块读写文件fread、fwrite
================================================================================================
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:以数据块的方式给文件写入内容
参数:
    ptr:准备写入文件数据的地址
    size: size_t 为 unsigned int类型,此参数指定写入文件内容的块数据大小
    nmemb:写入文件的块数,写入文件数据总大小为:size * nmemb
    stream:已经打开的文件指针
返回值:
    成功:实际成功写入文件数据的块数目,此值和 nmemb 相等
    失败:0

-----------------------------------------------------------------------------------------------
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:以数据块的方式从文件中读取内容
参数:
    ptr:存放读取出来数据的内存空间
    size: size_t 为 unsigned int类型,此参数指定读取文件内容的块数据大小
    nmemb:读取文件的块数,读取文件数据总大小为:size * nmemb
    stream:已经打开的文件指针
返回值:
    成功:实际成功读取到内容的块数,如果此值比nmemb小,但大于0,说明读到文件的结尾。
    失败:0
    0: 表示读到文件结尾。(feof())
按照块读写文件fread、fwrite
复制代码

 

复制代码
文件指针移动:fseek、ftell、rewind
================================================================================================
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
功能:移动文件流(文件光标)的读写位置。
参数:
    stream:已经打开的文件指针
    offset:根据whence来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence往右移动,如果是负数,则相对于whence往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再次写入时将增大文件尺寸。
    whence:其取值如下:
        SEEK_SET:从文件开头移动offset个字节
        SEEK_CUR:从当前位置移动offset个字节
        SEEK_END:从文件末尾移动offset个字节
返回值:
    成功:0
    失败:-1
    
-----------------------------------------------------------------------------------------------
#include <stdio.h>
long ftell(FILE *stream);
功能:获取文件流(文件光标)的读写位置。
参数:
    stream:已经打开的文件指针
返回值:
    成功:当前文件流(文件光标)的读写位置
    失败:-1
    
-----------------------------------------------------------------------------------------------
#include <stdio.h>
void rewind(FILE *stream);
功能:把文件流(文件光标)的读写位置移动到文件开头。
参数:
    stream:已经打开的文件指针
返回值:
    无返回值
文件指针移动:fseek、ftell、rewind
复制代码

 

复制代码
Windows和Linux文本文件区别
================================================================================================
Windows和Linux文本文件区别
    b是二进制模式的意思,b只是在Windows有效,在Linux用r和rb的结果是一样的
    Unix和Linux下所有的文本文件行都是\n结尾,而Windows所有的文本文件行都是\r\n结尾
    在Windows平台下,以“文本”方式打开文件,不加b:
        当读取文件的时候,系统会将所有的 "\r\n" 转换成 "\n"
        当写入文件的时候,系统会将 "\n" 转换成 "\r\n" 写入 
        以"二进制"方式打开文件,则读\写都不会进行这样的转换
    在Unix/Linux平台下,“文本”与“二进制”模式没有区别,"\r\n" 作为两个字符原样输入输出

Linux和windows文件区别:
    1)对于二进制文件操作, Windows 使用“b”, Linux下二进制和文本没区别。
    2)windows下,回车 \r, 换行 \n。 \r\n  , Linux下 回车换行\n
    3) 对文件指针,先写后读。windows和Linux效果一致。
               先读后写。Linux无需修改。windows下需要在写操作之前添加 fseek(fp, 0, SEEK_CUR); 来获取文件读写指针,使之生效。
Windows和Linux文本文件区别
复制代码

 

 

复制代码
获取文件状态:stat();删除文件、重命名文件名:remove()、rename()
================================================================================================
#include <sys/types.h>
#include <sys/stat.h>
int stat(const char *path, struct stat *buf);
功能:获取文件状态信息
参数:
path:文件名
buf:保存文件信息的结构体
返回值:
成功:0
失败-1

-----------------------------------------------------------------------------------------------
#include <stdio.h>
int remove(const char *pathname);
功能:删除文件
参数:
    pathname:文件名
返回值:
    成功:0
    失败:-1
    
-----------------------------------------------------------------------------------------------
#include <stdio.h>
int rename(const char *oldpath, const char *newpath);
功能:把oldpath的文件名改为newpath
参数:
oldpath:旧文件名
newpath:新文件名
返回值:
成功:0
失败: - 1
获取文件状态:stat();删除文件、重命名文件名:remove()、rename()
复制代码

 

 

复制代码
文件缓冲区;更新缓冲区fflush()
=============================================================================================
文件缓冲区
ANSI C标准采用“缓冲文件系统”处理数据文件。
所谓缓冲文件系统是指系统自动地在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。
如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(给程序变量) 。


缓冲区刷新:【不管输入还是输出,数据首先先进入到内存中的文件缓冲区,然后根据缓冲机制(行缓冲、全缓冲、无缓冲)将数据刷新到屏幕or磁盘等物理设备】
    标准输出-- stdout -- 标准输出缓冲区。   写给屏幕的数据,都是先存缓冲区中,由缓冲区一次性刷新到物理设备(屏幕)
    标准输入 -- stdin -- 标准输入缓冲区。    从键盘读取的数据,直接读到 缓冲区中, 由缓冲区给程序提供数据。

    预读入、缓输出。
    行缓冲:printf(); 遇到\n就会将缓冲区中的数据刷新到物理设备上。
    全缓冲:文件。 缓冲区存满, 数据刷新到物理设备上。
    无缓冲:perror。 缓冲区中只要有数据,就立即刷新到物理设备。

    
    文件关闭时, 缓冲区会被自动刷新。  隐式回收:关闭文件、刷新缓冲区、释放malloc
    手动刷新缓冲区: 实时刷新。

------------------------------------------------------------------------------------------
更新缓冲区fflush()
    #include <stdio.h>
    int fflush(FILE *stream);
    功能:更新缓冲区,让缓冲区的数据立马写到文件中。
    参数:
    stream:文件指针
    返回值:
    成功:0
    失败:-1
文件缓冲区;更新缓冲区fflush()
复制代码

 

posted @   雲淡風輕333  阅读(311)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示