c语言操作文件(待补充)
内容概要
一、打开和关闭文件
二、打开文件的几种模式
三、文本模式:fputc,fgetc,fputs,fgets,fscanf,fprintf
四、二进制模式:fwrite,fread
五、文件操作小练习
1、打开和关闭文件
fopen(字符串参数一,字符串参数二);
功能:打开文件
参数:参数一,文件名,可以是相对路径,也可以是绝对路径,默认为当前路径
参数二,打开文件的模式(注意这里必须是字符串而不是字符)
返回值:文件指针或NULL
fclose(文件指针)
功能:关闭文件
返回值:整形(应该用于表示函数是否执行成功)
使用typedef类型FILE *定义文件指针
#include <stdio.h> #include <stdlib.h> int main(void){ FILE *pfp; pfp = fopen("hello.txt", "w"); if (pfp == NULL){ printf("open file error!\n"); //文件打开失败时返回NULL exit(EXIT_FAILURE); } fclose(pfp); pfp = NULL; //pfp依旧存有文件的地址,但是那个空间已经被释放了 return 0; }
注意:和python的open()函数一样,fopen()只是向操作系统发送打开文件的请求,如果不使用fclose,那么这部分资源不会被操作系统释放,即使你关闭了可执行程序
2、打开文件的几种模式
c语言文件打开的模式与python是一样的
| r | 以只读方式打开文件,该文件必须存在。 |
| r+ | 以读/写方式打开文件,该文件必须存在。 |
| rb+ | 以读/写方式打开一个二进制文件,只允许读/写数据。 |
| rt+ | 以读/写方式打开一个文本文件,允许读和写。 |
| w | 打开只写文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。 |
| w+ | 打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。 |
| a | 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。 |
| a+ | 以附加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。 |
| wb | 以只写方式打开或新建一个二进制文件,只允许写数据。 |
| wb+ | 以读/写方式打开或建立一个二进制文件,允许读和写。 |
| wt+ | 以读/写方式打开或建立一个文本文件,允许读写。 |
| at+ | 以读/写方式打开一个文本文件,允许读或在文本末追加数据。 |
| ab+ | 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。 |
默认情况下为t文本模式
"w" => "wt"
二进制和文本模式的区别:
在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。
在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。
在mac操作系统下,文本模式以\r表示换行,fputs等函数写入换行符"\n"时,会被替换为\r。
c语言在文件末尾处会添加一个结束符EOF(-1)表示文件已经读取完毕
3、文本模式
fputc(整形表示字符常量的ascii编码值,文件指针)
// file put char的意思
功能:往文件中添加一个字符
返回值:整形
fgetc(文件指针)
// flie get char的意思
功能:从文件中拿取一个字符
返回值:字符常量的ascii编码值
#include <stdio.h> #include <stdlib.h> int main(void){ FILE *file; int ch; file = fopen("hello.txt", "r"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } /*while ((ch = fgetc(file)) != EOF){ printf("%c", ch); }*/ do { ch = fgetc(file); if (ch == EOF){ printf("%d", ch); } } while (ch != EOF); putchar('\n'); fclose(file); file = NULL; return 0; }
fputs(字符指针或数组,文件指针)
// file put string的意思
功能:往文件中写入一个字符串,字符串自动添加的\0会被忽略
返回值:整形
检验fputs会将字符串自动添加的\0去掉
这段代码在windows下dev-c++下是能找到\0的;在虚拟机上就进入死循环了
#include <stdio.h> #include <stdlib.h> int main(void){ FILE *fp; int c; if ((fp = fopen("hello.txt", "w")) == NULL){ printf("open the file error!\n"); exit(EXIT_FAILURE); } fputs("hello world", fp); while (1){ c = fgetc(fp); if (c == '\0'){ printf("find the char \\0\n"); break; } } return 0; }
fgets(字符指针或者数组,读取字符的数量size,文件指针)
// file get string的意思
功能:往文件种读取一个字符串
参数:参数一,参数一用于存放得到字符串
参数二,参数二用于限制读取到的字符数量,注意读取到的字符串会自动加上\0,所以实际得到的字符数量为(size-1),同时size-1表示读取的最大字符数量,如果在读取过程中遇到\n,则结束读取
fprintf(文件指针,写入文件的字符串格式,传入占位符的实际数据)
功能:类似printf将数据格式化输出到终端,fprintf是将数据输出到文件上
fscanf(文件指针,按怎样的格式将文件中的数据读取到内存,用于存储相应值得变量地址1,地址2...)
功能:格式化将文件内容读取到并保存到变量中
time.h库
#include <stdio.h> #include <time.h> int main(void){ struct tm *time1; //这里必须是指针,不是结构体变量 time_t t; time(&t); //这是时间戳 printf("t:%lld\n", t); time1 = localtime(&t); //将时间戳解析 printf("tm_sec:%d\n", time1.tm_sec); // 秒,从0到59 printf("tm_min:%d\n", time1.tm_min); // 分,从0到59 printf("tm_hour:%d\n", time1.tm_hour); // 小时,从0到23 printf("tm_mday:%d\n", time1.tm_mday); // 一个月的第几天,从1到31 printf("tm_mon:%d\n", time1.tm_mon); // 月,从0到11 printf("tm_year:%d\n", time1.tm_year); // 自1900年起的年数 printf("tm_wday:%d\n", time1.tm_wday); // 一周中的第几天,范围从0到6 printf("tm_yday:%d\n", time1.tm_yday); // 一年中的第几天,范围从0到365 printf("tm_isdst:%d\n", time1.tm_isdst); // 夏令时 return 0; }
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void){ struct tm *ptm; time_t t; time(&t); ptm = localtime(&t); FILE *fp; if ((fp = fopen("hello.txt", "w")) == NULL){ printf("open the file error!\n"); exit(EXIT_FAILURE); } fprintf(fp, "%d-%d-%d", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday); fclose(fp); if ((fp = fopen("hello.txt", "r")) == NULL){ printf("open the file error!\n"); exit(EXIT_FAILURE); } int year, month, day; fscanf(fp, "%d-%d-%d", &year, &month, &day); fclose(fp); fp = NULL; printf("year:%d, month:%d, day:%d\n", year, month, day); return 0; }
4、二进制模式:fread,fwrite
文本模式下的文件中的数据本质还是二进制方式存储的,只是中间做了一层转换,变成人能识别的字符(英语符号,汉语,日语,法语等)
这个转换关系就是字符编码
fread(用于指向存储位置的任意类型的指针, 每个元素的大小,元素个数,文件指针)
功能:读取二进制数据
返回值:无符号long long(表示读取成功的元素数量)
fwrite(任意类型的指针, 每个元素的大小,元素个数,文件指针)
功能:类似python中json模块和pickle模块,可以实现将非字符(结构体等)以二进制形式存储到文件中
返回值:无符号long long(表示写入成功的元素数量)
以二进制模式写入文件,以文本模式读取内容
#include <stdio.h> #include <stdlib.h> int main(void){ FILE *file; int a = 67, *pa = &a; int ch; file = fopen("hello.txt", "wb"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } fwrite(pa, 4, 1, file); fclose(file); file = NULL; file = fopen("hello.txt", "a"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } ch = fgetc(file); printf("%c\n", ch); //这里打印了大写的C,因为67就是大写字母C的asciii编码值 fclose(file); file = NULL; return 0; }
二进制模式存放/读取结构体变量
结构体存放
#include <stdio.h> #include <stdlib.h> struct Book{ char name[32]; char author[32]; float price; }; typedef struct Book To_book, *P_to_book; int main(void){ FILE *file; P_to_book pbook1; int num; To_book book1 = { "hahahaha", "emmmmmmm", 52.2, }; pbook1 = &book1; file = fopen("hello.txt", "rb"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } num = fwrite(pbook1, sizeof(To_book), 1, file); printf("%llu\n", num); fclose(file); file = NULL; return 0; }
结构体读取
#include <stdio.h> #include <stdlib.h> struct Book{ char name[32]; char author[32]; float price; }; typedef struct Book To_book, *P_to_book; int main(void){ FILE *file; P_to_book pbook1; int num; file = fopen("hello.txt", "rb"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } num = fread(pbook1, sizeof(To_book), 1, file); printf("num : %llu\n", num); fclose(file); file = NULL; return 0; }
存放数组
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void){ FILE *file; char str[20] = "hello world"; char *pstr; int length = strlen(str); int num; pstr = str; file = fopen("hello.txt", "wb"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } num = fwrite(pstr, length, 1, file); printf("num : %u\n", num); fclose(file); file = NULL; return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void){ FILE *file; char str[20] = "hello world"; char *pstr; int num; pstr = str; file = fopen("hello.txt", "wb"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } num = fwrite(pstr, sizeof(str), 1, file); printf("num : %u\n", num); fclose(file); file = NULL; return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void){ FILE *file; char str[20] = "hello world"; int num; file = fopen("hello1.txt", "wb"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } num = fwrite(str, sizeof(str), 1, file); printf("num : %u\n", num); fclose(file); file = NULL; return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void){ FILE *file; char str[20] = "hello world"; char *pstr; int num; pstr = str; file = fopen("hello1.txt", "wb"); if (file == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } num = fwrite(pstr, 1, 11, file); printf("num : %u\n", num); fclose(file); file = NULL; return 0; }
说白了,c语言其实没有对语法那么严格,终究遵照 内存地址+数据长度+解析方式
尝试对其它类型的数组(指针数组,整形数组和结构体数组)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 5 struct Book{ char name[20]; char author[20]; float price; }; typedef struct Book To_book; int main(void){ FILE *file; To_book library[N]; if ((file = fopen("hello.txt", "wb")) == NULL){ printf("open file error!n"); exit(EXIT_FAILURE); } for (int i = 0; i < N; i++){ printf("please input information about the book(for example helloworld haha 52.1):\n"); scanf("%s %s %f", library[i].name, library[i].author, &library[i].price); } fwrite(library, sizeof(To_book), N, file); fclose(file); file = NULL; if ((file = fopen("hello.txt", "ab")) == NULL){ printf("open file error!|n"); exit(EXIT_FAILURE); } int *array[N]; int a; for (int i = 0; i < N; i++){ array[i] = &a; } fwrite(array, sizeof(int *), N, file); fclose(file); file = NULL; return 0; }
5、文件操作小练习
一个创建文件并且传入字符串的小功能
#include <stdio.h> void un_user_char(void); void put_str(FILE *); void un_user_char(void){ while (getchar() != '\n'){ ; } } void put_str(FILE *file){ char str[1024]; printf("please input a string:"); scanf("%s", str); fputs(str, file); } int main(void){ char choice; char filename[20]; FILE *file; printf("please input filename:"); scanf("%s", filename); un_user_char(); file = fopen(filename, "w"); if (file == NULL){ printf("open file error!\n"); } while (1){ printf("please input if you want to add string(y/n):"); scanf("%c", &choice); un_user_char(); if ('y' == choice){ put_str(file); un_user_char(); } else if ('n' == choice){ break; } else { printf("please input a qualified cammond!\n"); } } fclose(file); file = NULL; return 0; }
-实现一个复制的小功能
**main(int argc, char *argv[])解析**
#include <stdio.h> #include <stdlib.h> #include <string.h> #define ONE_GET_MAX 1024 int main(int argc, char *argv[]){ FILE *file = NULL, *file_cpy = NULL; if ((file = fopen(argv[1], "rb")) == NULL){ printf("open file error!\n"); exit(EXIT_FAILURE); } if ((file_cpy = fopen(argv[2], "wb")) == NULL){ printf("create file error!\n"); exit(EXIT_FAILURE); } char *pstr = (char *)malloc(sizeof(1024)); while (!feof(file)){ fread(pstr, ONE_GET_MAX ,1 ,file); fwrite(pstr, strlen(pstr), 1, file_cpy); } fclose(file); fclose(file_cpy); file = NULL; file_cpy = NULL; return 0; }
最后一个练习
结合之前内容,完成一个添加书籍的功能
***待补充***
本文来自博客园,作者:口乞厂几,转载请注明原文链接:https://www.cnblogs.com/laijianwei/p/14585532.html

浙公网安备 33010602011771号