admin管理员组

文章数量:1794759

C语言:文件操作

C语言:文件操作

文件操作

系统文件

标准输入:stdin,编号0,printf-标准输出
标准输出:stdout,编号1,scanf-标准输入
标准错误:stderr,编号2,perror-标准错误
应用程序启动时,自动被打开;程序执行结束时,自动被关闭

文件指针
  • 文件指针定义:FILE *fp;
  • 文件指针初始化:fp = fopen();
  • 操作文件:使用文件读写函数来完成,fputc,fgets,fputs,fgets,fread,fwrite等
文件分类
  • 设备文件
    屏幕、键盘、磁盘、网卡、声卡、显卡、扬声器等
  • 磁盘文件
    文本文件:字符表示数据
    二进制文件:字节表示数据
文件操作步骤
  1. 打开文件fopen()

FILE* fopen(const char* filename,const char* mode);
参数1-filename:待打开文件的文件名(访问路径)
参数2-mode:文件操作权限
返回值:成功返回打开文件的文件指针;失败返回NULL

1.mode
r/rb:以只读方式打开文件,若文件不存在则报错
w/wb:以写方式打开文件,若文件不存在则新建,若存在则清空
a/ab:以追加方式打开文件,若文件不存在则新建,若存在则在末尾追加内容
r+/rb+:以可读可写方式打开文件(不创建新文件)
w+/wb+:以可读可写方式打开文件(若文件不存在则新建,若存在则清空)
a+/ab+:以追加方式打开可读可写文件(若文件不存在则新建,若存在则在末尾追加内容)
2.b是二进制模式的意思,只在windows有效,linux上两种形式作用一样
3.linux下文件行尾以\n结尾,windows下文件行尾以\r\n结尾

  1. 读写文件

  2. 关闭文件fclose()

int fclose(FILE* stream);
参数1-stream:打开文件的文件指针(fopen的返回值)
返回值:成功0,失败-1

访问路径
1.相对路径
vs环境下
编译执行,文件相对路径是指相对于工程文件所在文件目录位置;
双击可执行文件执行,相对路径指相对于可执行文件所在目录位置。
2.绝对路径:从系统磁盘根盘符开始,到待访问文件的完整路径

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(void)
{FILE* fp = NULL;//fp = fopen("F:/test/test.txt","r");fp = fopen("F:\\test\\test.txt","r");if (fp == NULL){perror("fopen error");return -1;}fclose(fp);return 0;
}
文件操作函数
  • 按字符写文件fputc

int fputc(int ch,FILE* stream);
参数1-ch:待写入的字符
参数2-stream:打开文件的fp
返回值:写入成功返回写入字符的ascii码,失败返回-1

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main02() {FILE* fp = fopen("F:/test/test.txt","w");if (fp == NULL) {perror("fopen error");return -1;}for (size_t i = 0; i < 26; i++){char ch = fputc('a'+i, fp);if (ch == -1) {perror("fputc error");return -1;}printf("%c", ch);}fclose(fp);return 0;
}
  • 按字符读文件fgetc

int fgetc(FILE* stream);
参数:待读取的文件指针
返回值:成功返回读取到的字符的ascii,失败返回-1;

文本文件的结束标记:EOF(-1)

void read_file() {FILE* fp = fopen("F:/test/test.txt", "r");if (fp == NULL) {perror("fopen error");return;}char ch = fgetc(fp);while (ch != -1) {printf("%c ", ch);ch = fgetc(fp);}fclose(fp);
}
  • feof

int feof(FILE* stream);
函数作用:判断是否到达文件结尾
参数:fopen返回值
返回值:到达文件结尾返回非0【真】,没有到达文件结尾返回0【假】

文本文件由ascii组成,asciima范围是0~127,正文不会出现-1,所以可以用EOF(-1)判断是否到达结尾;二进制文件正文可能会存在-1,可以使用feof判断是否到达文件结尾。

void read_file() {FILE* fp = fopen("F:/test/test.txt", "r");if (fp == NULL) {perror("fopen error");return;}char ch = fgetc(fp);while (1) {if (feof(fp)) {break;}printf("%c ", ch);ch = fgetc(fp);}fclose(fp);
}
  • 按行读写文件

char* fgets(char* str,int size,FILE* stream);
函数功能:从stream指定文件读取字符串保存到str指定内存空间,直到出现换行或文件尾或已读size-1个字符为止,末尾自动添加’\0’
参数1-str:读取到的字符串
参数2-size:指定最大读取字符串长度(size-1)
参数3-stream:文件指针
返回值:成功返回读取到的字符串,读到文件尾或出错返回NULL

int fputs(const char* str,FILE* stream);
函数功能:将str指定的字符串写入到stream指定文件中,字符串’\0’不写入文件
参数1-str:字符串
参数2-stream:文件指针
返回值:成功0,失败-1

案例:获取键盘输入写入文件

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(void)
{FILE* fp = fopen("F:/test/test.txt","a");if (fp == NULL) {perror("fopen error");return -1;}char buf[4096];while (1) {fgets(buf,4096,stdin);if (strcmp(buf, ":wq\n") == 0) {break;}fputs(buf, fp);}fclose(fp);return 0;
}
操作文本文件
  • fprintf():写指定格式内容到文件中

int fprintf(FILE* stream,const char* format,...);

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(void)
{FILE* fp = fopen("F:/test/test03.c", "w");if (fp == NULL) {perror("fopen error");return -1;}fprintf(fp, "%d%c%d=%d\n", 10, '*', 7, 10 * 7);fclose(fp);return 0;
}
  • fscanf():

int fscanf(FILE* stream,const char* format,...);

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {FILE* fp = fopen("F:/test/test03.c", "r");if (fp == NULL) {perror("fopen error");return -1;}int a, b, c;char ch;fscanf(fp, "%d%c%d=%d\n", &a, &ch, &b, &c);printf("%d%c%d=%d\n", a, ch, b, c);fclose(fp);return 0;
}
操作二进制文件
  • fwrite():将数据写入文件

size_t fwrite(const void* ptr,size_t size,size_t nmemb,FILE* stream);
参数1-ptr:待写出数据的地址
参数2-size:待写出数据的大小
参数3-nmemb:写出次数(size*nmemb=写出数据总大小)
参数4-stream:文件
返回值:成功返回写入文件次数(参3的值),失败返回0

  • fread()从文件读取数据

size_t fread(const void* ptr,size_t size,size_t nmemb,FILE* stream);
参数1-ptr:读取出的数据的存储的地址
参数2-size:一次读取字节数
参数3-nmemb:读取次数(size*nmemb=读出数据总大小)
参数4-stream:文件
返回值:成功返回读取文件次数(参3的值),失败返回0

随机位置读

文件读写指针,一个文件内只有一个

  • fseek():修改文件指针位置

int fseek(FILE* stream,long offset,int whence);
参数1-stream:文件
参数2-offset:偏移量(+向后,-向前)
参数3-whence:SEEK_SET(文件开头),SEEK_CUR(文件当前位置),SEEK_END(文件结尾位置)
返回值:成功0,失败-1

  • ftell():获取文件读写指针位置

long ftell(FILE* stream);
返回值:从文件当前读写位置到起始位置的偏移量

  • rewind():把文件读写指针重置到文件开头

void rewind(FILE* stream);

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {FILE* fp = fopen("F:/test/test08.txt", "r+");if (fp == NULL) {perror("fopen error");}char buf[6];fputs("111112222233333", fp);rewind(fp);//文件读写指针为同一个,不重置指针会继续往后读取数据,从而造成读不到数据的结果;也可通过fseek修改文件指针位置fgets(buf, 6, fp);printf("buf = %s", buf);fclose(fp);return 0;
}
linux和windows文件区别
  1. 对于二进制文件操作,windows下模式要添加"b",linux下二进制和文本文件打开文件模式没有区别
  2. windows下回车是\r,换行是\n,一行结尾的字符是\r\n;linux下回车换行是\n,一行结尾是\n
  3. 对文件指针,先写后读,windows和linux效果一致;先读后写,windows下需要在写操作之前使用fseek(fp,0,SEEK_CUR)使文件读写指针生效,linux无效修改可直接进行写操作
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(void)
{FILE* fp = fopen("F:/test/test08.txt", "r+");if (fp == NULL) {perror("fopen error");return -1;}char buf[6] = {0};char* ptr = fgets(buf, 6, fp);printf("buf=%s,ptr=%s\n", buf,ptr);fseek(fp, 0, SEEK_CUR);//windows下先读后写的写操作前需要使用该函数,linux下不需要使用,可以直接进行写入int ret = fputs("AAAAA", fp);printf("ret=%d\n", ret);fclose(fp);return 0;
}
获取文件状态
  • 获取文件状态

int stat(const char* path,struct stat* buf);
参数1-path:访问文件路径
参数2-buf:文件属性结构体
返回值:成功0,失败-1

使用该函数需要使用头文件:<sys/types.h>、<sys/stat.h>

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<sys/types.h>
#include<sys/stat.h>int main(void)
{struct stat buf;int ret = stat("F:/test/test08.txt", &buf);//传出参数:函数调用完毕时充当函数返回值printf("文件大小:%d\n", buf.st_size);return 0;
}
删除、重命名文件
  • 删除文件

int remove(const char* pathname);

  • 重命名文件

int rename(const char* oldpath,const char* new path);

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main() {//remove("F:/test/test07.txt");rename("F:/test/test05.txt", "F:/test/改名.txt");return 0;
}
缓冲区刷新

(缓输出)标准输出–stdout–标准输出缓存区:写给屏幕的数据,先输出到缓存区,由缓冲区一次性刷新到物理设备(屏幕)

(预读入)标准输入-- stdin–标准输入缓冲区:从键盘读取的数据直接读到缓冲区,由缓冲区给程序提供数据

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

自动刷新缓冲区:文件关闭时缓冲区会被自动刷新

手动刷新缓冲区:
int fflush(FILE* stream);
返回:成功0,失败-1

本文标签: C语言文件操作