凡是字符串参数都可以替换为字符数组参数
路径
- Linux下:路径写作
"./..." - windows下:路径写作如
c:\\...或者c:/...盘符大小写都可以 路径不存在必须先创建路径。文件不存在可以自动创建,路径文件夹不会
windows下的坑
我的c盘默认就是任何一个位置的更改都需要管理员的权限。那就必须以管理员身份运行ide再编译运行或者直接以管理员身份运行exe文件才能操作成功 否则执行后就没有任何变化
建立文件流
创建FILE对象并且借助fopen确定路径和访问模式
FILE *fp; fp = fopen("./tmp/test.txt", "w+"); 或者FILE *fp = fopen("./tmp/test.txt", "w+");
- 借助fopen函数,该函数可以创建一个文件(配合访问模式)并创建文件流或者对一个已经存在的文件创建文件流
- 如果没有这个文件,访问模式又不允许创建这个文件,文件对象就返回null并且产生一个错误
FILE *fopen( const char * filename, const char * mode );
- fopen会调用FILE对象,该对象包含所有控制流的信息。
- filename为文件名
- mode为访问模式(文件打开方式),有如下参数
带+即表示即可读取又可以写入 | 模式 | 描述 | | —- | —- | | r | 打开一个已有的文本文件,允许读取文件。 | | w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。这个w好像如果存在也会清空再进行写入 | | a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 追加即末尾开始写入 | | r+ | 打开一个文本文件,允许读写文件。 | | w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度(即清空文件内容再写入)如果文件不存在,则会创建一个新文件。 | | a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 即写入时a+等同于a |
如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式:"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
即添加b或者b+ 具体作用见https://blog.csdn.net/observadores/article/details/79305470
读取文件
int fgetc( FILE * fp );读取一个字符,位置后移一位,配合循环即可读取全部数据 成功返回字符 失败返回EOFchar *fgets( char *buf, int n, FILE *fp );读取n - 1 个字符。它会把读取的字符串复制到缓冲区buf,并在最后追加一个null字符来终止字符串。 如果这个函数在读取最后一个字符之前就遇到一个换行符 ‘\n’ 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。int fscanf(FILE *fp, const char *format, ...)format不清楚是不是缓冲区 该函数读取到空格会停止读取关闭文件流
建立FILE文件流后记得关闭流
int **fclose**( FILE *fp );这个函数会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。
如果成功关闭文件,fclose( )函数返回零,如果关闭文件时发生错误,函数返回EOF0。
int fputc( int c, FILE *fp );写入一个字符,位置后移一位
函数fputc()把参数 c 的字符值写入到 fp 所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回EOF。
int fputs( const char *s, FILE *fp );把一个以 null 结尾的字符串写入到流中 s为要写入的字符串
写入成功,返回非负值。失败返回EOF
int fprintf(FILE *fp,const char *format, ...)写入一个字符串 format为要写入的字符串
fprintf和fputs差不多,就是2个参数的位置换了下
#include <stdio.h>int main(){FILE *fp;fp = fopen("c://test.txt", "w+");fprintf(fp, "This is testing for fprintf...\n");fputs("This is testing for fputs...\n", fp);fclose(fp);}
二进制读取与写入
- 二进制读取与写入需要给出字符串的元素数和元素大小。
下面两个函数用于二进制输入和输出:
size_t fread(void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file;参考fwrite
size_t fwrite(const void *ptr, size_t size_of_elements, size_t number_of_elements, FILE *a_file);把字符串中的数据写入到文件流当中
- size_of每个元素的大小(byte单位) number_of为写入元素的个数
- 记住字符串的元素总数会比看到的个数多1,因为字符串末尾会有一个null字符’\0’
- 参数number_of可以小于等于字符串长度 即给定看到字符串的个数即可把全部的字符写入文件,不需要再写入’\0’ 给大于字符串的长度则出现c错误(写入些乱码字符)
- 写入成功返回size-t对象,表示写入元素总数(int型) 如果返回的总数与参数中的总数number不同,即写入发生了错误
```c
include
int main () { FILE *fp; char str[] = “This is runoob.com”;
fp = fopen( “file.txt” , “w” ); int b=fwrite(str, sizeof(str) , 4, fp ); //写入4个字符 printf(“%d”,b); fclose(fp); return(0);
//输出b=4=给定的参数4 正确写入 file.txt内容为This }
这两个函数都是用于存储块的读写 - 通常是数组或结构体。<a name="Rvd5T"></a># 指针位置操作- `void rewind(FILE *file)`**将位置指针移动至文件的开头 可以用于写入后再移动至开头进行读取**- `int fseek(FILE *stream, long int offset, int whence)` 将位置指针从whence的位置往后偏移offset个字符 offset即偏移量- 成功返回0 失败返回非0值- whence可以是如下常量:| 常量 | 描述 || --- | --- || SEEK_SET | 文件的开头 || SEEK_CUR | 文件指针的当前位置 || SEEK_END | 文件的末尾 |- `fgetpos(FILE *stream, fpos_t *pos)` 获取当前位置并写入到pos中- pos是fpos_t对象的指针 使用时需要创建一个fpos_t的对象 getpos和setpos的pos参数需要取地址来使用如`fpos_t position; fget/setpos(fp, &position);`- `fsetpos(FILE *stream, const fpos_t *pos)` 将位置设置为pos参数的位置```c#include <stdio.h>int main (){FILE *fp;fpos_t position;fp = fopen("file.txt","w+");fgetpos(fp, &position);fputs("Hello, World!", fp);fsetpos(fp, &position);fputs("这将覆盖之前的内容", fp);fclose(fp);return(0);}输出为"这将覆盖之前的内容" 因为在创建文件流后位置开始处于开头,使用getpos将开头这个位置写入了position中 写入时也就从开头写入,覆盖掉了helloworld
fseek的注意点
- 一个字符串他的位置指针是0开始的(毕竟c语言中字符串就是个字符数组) 读写将从偏移到的位置的下一个位置开始
- 因为w和w+会清空文件进行写入,而a和a+是末尾追加写入 所以如果要覆盖操作就得借助fseek才能覆盖操作
如This`` fseek(?,2,SEEK_SET) 是开头偏移了2个字符到i 写入一个字符a将在i后开始操作,得到Thia a覆盖了s
文件状态检测
int feof(FILE *stream)检查文件是否结束(检查位置是否处于结束符’\0’) 如果未结束,返回0 已经结束,返回非0 注意与一般逻辑相反 配合循环和fputc或者fgetc的自动后移一位可以读写文件 ```cinclude
int main () { FILE *fp; int c;
fp = fopen(“file.txt”,”r”); if(fp == NULL) { perror(“打开文件时发生错误”); //如果上一个函数产生错误,则输出错误信息 即如果fopen发生错误(即如果文件不存在,访问模式又不允许创建这个文件,就产生错误) return(-1); } while(1) //无限循环 { c = fgetc(fp); if( feof(fp) ) //fgetc自动后移。如果移动到字符串结尾的’\0’就会返回非0值,则退出无限循环 { break ; } printf(“%c”, c); } fclose(fp); return(0); } ```
文件操作异常处理
int ferror(FILE *stream)如果产生文件操作错误就返回一个非0值- 配合if使用可以进行异常处理 如
if(ferror(file)){printf("文件操作发生错误");}
- 配合if使用可以进行异常处理 如
void clearerr(FILE *stream)文件操作发生错误可以使用该函数进行清楚错误信息(FIlE操作失败可能是文件不存在 或者访问模式与要进行的操作不一致,如只读模式进行写操作)
更多实例
https://www.w3cschool.cn/c/c-file-io.html末尾
总结
- putc,getc是读写字符 puts和gets是读写字符串
- printf和scanf是格式化读写字符串
- write和read是二进制读写字符串
