一次读写一块数据
- C 语言己经从接口的层面区分了,文本的读写方式和二进制的读写方式。前面我们讲的是文本的读写方式。
- 所有的文件接口函数,要么以 '\0',表示输入结束,要么以 '\n', EOF(0xFF)表示读取结束。'\0' '\n' 等都是文本文件的重要标识,而所有的二进制接口对于这些标识,是不敏感的。+二进制的接口可以读文本,而文本的接口不可以读二进制
函数声明 |
int fwrite(void *buffer, int num_bytes, int count, FILE *fp) |
所在文件 |
stdio.h |
函数功能 |
把buffer 指向的数据写入fp 指向的文件中 |
参数 |
char * buffer : 指向要写入数据存储区的首地址的指针 |
|
int num_bytes: 每个要写的字段的字节数count |
|
int count : 要写的字段的个数 |
|
FILE* fp : 要写的文件指针 |
返回值 |
int 成功,返回写的字段数;出错或文件结束,返回 0。 |
- #include <stdio.h>
- #include <string.h>
-
- int main()
- {
- FILE *fp = fopen("test.txt", "wb+");
-
- char *str = "lnj\0it666";
-
-
- fwrite((void *)str, 9, 1, fp);
-
- fclose(fp);
- return 0;
- }
-
函数声明 |
int fread(void *buffer, int num_bytes, int count, FILE *fp) |
所在文件 |
stdio.h |
函数功能 |
把fp 指向的文件中的数据读到 buffer 中。 |
参数 |
char * buffer : 指向要读入数据存储区的首地址的指针 |
|
int num_bytes: 每个要读的字段的字节数count |
|
int count : 要读的字段的个数 |
|
FILE* fp : 要读的文件指针 |
返回值 |
int 成功,返回读的字段数;出错或文件结束,返回 0。 |
- #include <stdio.h>
-
- int main()
- {
-
- FILE *fr = fopen("test.txt", "rb+");
- char buf[1024] = {0};
-
-
-
- int n = fread(buf, 1, 1024, fr);
- printf("%i\n", n);
- for(int i = 0; i < n; i++){
- printf("%c", buf[i]);
- }
- fclose(fr);
- return 0;
- }
-
- 注意点:
- 读取时num_bytes应该填写读取数据类型的最小单位, 而count可以随意写
- 如果读取时num_bytes不是读取数据类型最小单位, 会引发读取失败
- 例如: 存储的是char类型 6C 6E 6A 00 69 74 36 36 36 如果num_bytes等于1, count等于1024, 那么依次取出 6C 6E 6A 00 69 74 36 36 36 , 直到取不到为止 如果num_bytes等于4, count等于1024, 那么依次取出[6C 6E 6A 00][69 74 36 36] , 但是最后还剩下一个36, 但又不满足4个字节, 那么最后一个36则取不到
-
-
-
- int main()
- {
-
- // test.txt中存放的是"lnj\0it666"
- FILE *fr = fopen("test.txt", "rb+");
- char buf[1024] = {0};
- /*
- while(fread(buf, 4, 1, fr) > 0){
- printf("%c\n", buf[0]);
- printf("%c\n", buf[1]);
- printf("%c\n", buf[2]);
- printf("%c\n", buf[3]);
- }
- */
- /*
- while(fread(buf, 1, 4, fr) > 0){
- printf("%c\n", buf[0]);
- printf("%c\n", buf[1]);
- printf("%c\n", buf[2]);
- printf("%c\n", buf[3]);
- }
- */
- while(fread(buf, 1, 1, fr) > 0){
- printf("%c\n", buf[0]);
- }
- fclose(fr);
- return 0;
- }
-
- 注意: fwrite和fread本质是用来操作二进制的
- 所以下面用法才是它们的正确打开姿势
- #include <stdio.h>
-
- int main()
- {
-
- FILE *fp = fopen("test.txt", "wb+");
- int ages[4] = {1, 3, 5, 6};
- fwrite(ages, sizeof(ages), 1, fp);
- rewind(fp);
- int data;
- while(fread(&data, sizeof(int), 1, fp) > 0){
- printf("data = %i\n", data);
- }
- return 0;
- }
-
读写结构体
- 结构体中的数据类型不统一,此时最适合用二进制的方式进行读写
- 读写单个结构体
-
-
- typedef struct{
- char *name;
- int age;
- double height;
- } Person;
-
- int main()
- {
- Person p1 = {"lnj", 35, 1.88};
- // printf("name = %s\n", p1.name);
- // printf("age = %i\n", p1.age);
- // printf("height = %lf\n", p1.height);
-
- FILE *fp = fopen("person.stu", "wb+");
- fwrite(&p1, sizeof(p1), 1, fp);
-
- rewind(fp);
- Person p2;
- fread(&p2, sizeof(p2), 1, fp);
- printf("name = %s\n", p2.name);
- printf("age = %i\n", p2.age);
- printf("height = %lf\n", p2.height);
-
- return 0;
- }
-
- #include <stdio.h>
-
- typedef struct{
- char *name;
- int age;
- double height;
- } Person;
-
- int main()
- {
- Person ps[] = {
- {"zs", 18, 1.65},
- {"ls", 21, 1.88},
- {"ww", 33, 1.9}
- };
-
-
- FILE *fp = fopen("person.stu", "wb+");
- fwrite(&ps, sizeof(ps), 1, fp);
-
- rewind(fp);
- Person p;
- while(fread(&p, sizeof(p), 1, fp) > 0){
- printf("name = %s\n", p.name);
- printf("age = %i\n", p.age);
- printf("height = %lf\n", p.height);
- }
- return 0;
- }
-
- #include <stdio.h>
- #include <stdlib.h>
-
- typedef struct person{
- char *name;
- int age;
- double height;
- struct person* next;
- } Person;
- Person *createEmpty();
- void insertNode(Person *head, char *name, int age, double height);
- void printfList(Person *head);
- int saveList(Person *head, char *name);
- Person *loadList(char *name);
-
- int main()
- {
-
-
-
-
-
-
-
- Person *head = loadList("person.list");
- printfList(head);
- return 0;
- }
-
-
- Person *loadList(char *name){
-
- FILE *fp = fopen(name, "rb+");
- if(fp == NULL){
- return NULL;
- }
-
- Person *head = createEmpty();
-
- Person *node = (Person *)malloc(sizeof(Person));
- while(fread(node, sizeof(Person), 1, fp) > 0){
-
-
- node->next = head->next;
-
- head->next = node;
-
-
- node = (Person *)malloc(sizeof(Person));
- }
-
- free(node);
- fclose(fp);
- return head;
- }
-
-
- int saveList(Person *head, char *name){
-
- FILE *fp = fopen(name, "wb+");
- if(fp == NULL){
- return -1;
- }
-
- Person *cur = head->next;
-
- while(cur != NULL){
- fwrite(cur, sizeof(Person), 1, fp);
- cur = cur->next;
- }
- fclose(fp);
- return 0;
- }
-
- void printfList(Person *head){
-
- Person *cur = head->next;
-
- while(cur != NULL){
-
- printf("name = %s\n", cur->name);
- printf("age = %i\n", cur->age);
- printf("height = %lf\n", cur->height);
- printf("next = %x\n", cur->next);
- printf("-----------\n");
-
- cur = cur->next;
- }
- }
-
-
- void insertNode(Person *head, char *name, int age, double height){
-
- Person *node = (Person *)malloc(sizeof(Person));
-
- node->name = name;
- node->age = age;
- node->height = height;
-
-
-
- node->next = head->next;
-
- head->next = node;
- }
-
- Person *createEmpty(){
-
- Person *head = NULL;
-
- head = (Person *)malloc(sizeof(Person));
- if(head == NULL){
- return head;
- }
- head->next = NULL;
-
- return head;
- }
-
其它文件操作函数
函数声明 |
long ftell ( FILE * stream ); |
所在文件 |
stdio.h |
函数功能 |
得到流式文件的当前读写位置,其返回值是当前读写位置偏离文件头部的字节数. |
参数及返回解析 |
|
参数 |
FILE * 流文件句柄 |
返回值 |
int 成功,返回当前读写位置偏离文件头部的字节数。失败, 返回-1 |
- #include <stdio.h>
-
- int main()
- {
- char *str = "123456789";
- FILE *fp = fopen("test.txt", "w+");
- long cp = ftell(fp);
- printf("cp = %li\n", cp);
-
- fputc(str[0], fp);
- cp = ftell(fp);
- printf("cp = %li\n", cp);
- fclose(fp);
- return 0;
- }
-
函数声明 |
void rewind ( FILE * stream ); |
所在文件 |
stdio.h |
函数功能 将文件指针重新指向一个流的开头。 |
|
参数及返回解析 |
|
参数 |
FILE * 流文件句柄 |
返回值 |
void 无返回值 |
- #include <stdio.h>
-
- int main()
- {
- char *str = "123456789";
- FILE *fp = fopen("test.txt", "w+");
- long cp = ftell(fp);
- printf("cp = %li\n", cp);
-
- fputc(str[0], fp);
- cp = ftell(fp);
- printf("cp = %li\n", cp);
-
- rewind(fp);
- cp = ftell(fp);
- printf("cp = %li\n", cp);
- fclose(fp);
- return 0;
- }
-
函数声明 |
int fseek ( FILE * stream, long offset, int where); |
所在文件 |
stdio.h |
函数功能 |
偏移文件指针。 |
参数及返回解析 |
|
参 数 |
FILE * stream 文件句柄 |
|
long offset 偏移量 |
|
int where 偏移起始位置 |
返回值 |
int 成功返回 0 ,失败返回-1 |
- #define SEEK_CUR 1 当前文字
- #define SEEK_END 2 文件结尾
- #define SEEK_SET 0 文件开头
-
- #include <stdio.h>
-
- int main()
- {
- FILE *fp = fopen("test.txt", "w+");
- fputs("123456789", fp);
-
- fseek(fp, 0, SEEK_END);
- int len = ftell(fp);
- printf("len = %i\n", len);
- fclose(fp);
- return 0;
- }
-
- #include <stdio.h>
-
- int main()
- {
- FILE *fp;
- fp = fopen("file.txt","w+");
- fputs("123456789", fp);
-
- fseek( fp, 7, SEEK_SET );
- fputs("lnj", fp);
- fclose(fp);
- return 0;
- }