复习C中文件操作

2023-10-17 12:36:04 浏览数 (1)

Ⅰ. 重新谈论文件

下面是对文件的一些共性认识:

​ 1、空文件 也要在磁盘中占据空间

​ 2、文件 = 内容 属性(Linux的文件内容和文件属性是分开存储的)

​ 3、文件操作 = 对内容操作 or 对属性操作 or 对内容和属性操作

​ 4、标定一个文件,必须通过:文件路径 文件名 (具有唯一性)

​ 5、如果没有指明文件路径,默认在当前路径下进行文件访问

​ 6、一个文件要 被访问之前必须先打开(文件被 用户进程操作系统 打开)

​ 7、文件操作的本质:进程 和 被打开文件 的 关系(未打开文件的属于文件系统,后面我们会讲)

Ⅱ. C语言中的文件接口

1、打开文件

代码语言:javascript复制
FILE* fopen(const char* filename, const char* mode);
// filename为文件名,若不加路径的话且该文件不存在的话则会在当前目录下创建该文件
// mode为打开方式,一般有r、w、a等等

文件打开方式

含义

如果指定文件不存在

“r”(只读)

为了输入数据,打开一个已经存在的文本文件

出错

“w”(只写)

为了输出数据,打开一个文本文件

建立一个新的文件

“a”(追加)

向文本文件尾添加数据

建立一个新的文件

“r ”(读写)

为了读和写,打开一个文本文件

出错

“w ”(读写)

为了读和写,新建一个新的文件

建立一个新的文件

“a ”(读写)

打开一个文件,在文件尾进行读写

建立一个新的文件

“rb”(二进制只读)

为了输入数据,打开一个二进制文件

出错

“wb”(二进制只写)

为了输出数据,打开一个二进制文件

建立一个新的文件

“ab”(二进制追加)

向一个二进制文件尾添加数据

出错

“rb ”(二进制读写)

为了读和写打开一个二进制文件

出错

“wb ”(二进制读写)

为了读和写,新建一个新的二进制文件

建立一个新的文件

“ab ”(二进制读写)

打开一个二进制文件,在文件尾进行读和写

建立一个新的文件

2、关闭文件

代码语言:javascript复制
int fclose(FILE* stream);
// stream是文件指针

3、读写函数

读取单个字符

fgetc(FILE* stream)

所有输入流

写入单个字符

fputc(int character, FILE stream)*

所有输出流

从文件中读取num个字符到str

fgets(char str, int num, FILE stream)**

所有输入流

写入一串字符到文件

fputs(const char str, FILE stream)**

所有输出流

将字符串转换为格式化数据

fscanf(FILE stream, const char format, …)**

所有输入流

将格式化数据转换为字符串

fprintf(FILE stream, const char format, …)**

所有输出流

二进制输入

size_t fread(void ptr, size_t size, size_t count, FILE stream)**

文件

二进制输出

size_t fwrite(const void ptr, size_t size, size_t count, FILE stream)**

文件

其中 freadrwrite 的参数解析如下:

  • ptr :从ptr指向的当前位置开始写入
  • size :每个元素的大小(以字节为单位)
  • count :要写入的元素个数
    • size 表示你要写入的基本单元是多大(以字节为单位),count 表示你要写入几个这样的基本单元。换言之,最终往文件中写的字节数是 = size * count,比如要写入 10 个字节,那么 size = 1 && count = 10、size = 2 && count = 5,不过一般建议把 size 写大点,count 写小点。
  • stream :指向输出流 FILE 对象的指针

4、文件的随机读写

① fseek函数(指定文件指针的位置)
代码语言:javascript复制
int fseek(FILE* stream, long int offset, int origin);
// stream:指向标识流的 FILE 对象的指针
// offset:指针偏移量
// origin:指针起始点

​ 其中 origin 起始点有如下三种:

SEEK_SET

文件开头

SEEK_CUR

文件指针的当前所处的位置

SEEK_END

文件结尾

② ftell函数(求文件指针与起始位置的偏移量)
代码语言:javascript复制
long int ftell(FILE* stream);
③ rewind(让文件指针回到起始位置)
代码语言:javascript复制
void rewind(FILE* stream);

5、文件读取结束的标志

  • 文本文件读取是否结束,fgetc判断返回值是否为 EOF, fgets判断返回值是否为 NULL
  • 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。 例如: fread判断返回值是否小于还是等于实际要读的个数。

feof:判断文件是否读到末尾而结束,返回值为真,就是读到了文件结束 ferror:判断文件是否读取错误而结束,返回值为真,就是文件读取遇到了错误

Ⅲ. C语言文件接口的使用及细节

  • “w” 的方式单纯打开文件,那么该文件的内容会被 清空
  • 当以 “w” 方式打开文件,它会建立一个新文件,它的 默认权限是0664(因为权限掩码umask为0666)
  • 在使用 fgets() 或者 fgetc() 时候,我们是按回车结束,而回车键也会被放到缓冲区内,所以我们如果要读取文件的时候并且不想带上 ‘n’ ,那么我们就要将接收到的字符串置为0即 buffer[strlen(buffer) - 1] = ‘’
  • 下面的代码中 strlen(msg) 1 -> 乱码,也就是把 ‘’ 也追加会造成,因为 ‘’ 是 C 的规定,和文件无关。这里 cat log.txt 并没有看到乱码的原因是 ‘’ 是不可见的,所以这里 vim log.txt 才可以看到乱码。
代码语言:javascript复制
#include<stdio.h>
#include<string.h>
int main()
{
    FILE* fp = fopen("log.txt", "a");//以追加的打开当前目录下的log.txt文件,没有就新建,如果目标文件存在,a写时不会清空目标文件,在文件内容最后写入
    if(fp == NULL)
    {
        perror("fopen");
        return 1;
    }

    const char* msg = "Hello linuxn";
    // fwrite(msg, strlen(msg)   1, 1, fp); // 乱码
    fwrite(msg, strlen(msg), 1, fp);                                                                               
    fclose(fp);
    return 0;
}

0 人点赞