文章目录
- IO(续上)
- 1.标准IO
- 1.标准IO的接口
- 2.流的定位
- 2.文件IO
- 1.概念:
- 2.系统调用和库函数
- 3.文件IO函数接口
- 习题
IO(续上)
1.标准IO
1.标准IO的接口
-
fwrite
原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream); 功能:向流中写入ptr指向的nmemb个对象,每个对象size个字节 参数:ptr:指向数据空间的首地址size:写入的每个对象的大小nmemb:写入对象的个数stream:文件流指针 返回值:成功返回实际写入对象的个数失败返回0
-
fread
原型: size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 功能:从流中读取nmemb个对象到ptr指向的空间中,每个对象size字节 参数:ptr:存放数据空间的首地址size:读取对象的字节大小nmemb:读取对象的个数stream:文件流指针 返回值:成功返回读到对象的个数失败或者读到文件末尾返回0
2.流的定位
-
作用:设置流的偏移量
-
偏移量的设置:
-
fseek
原型:int fseek(FILE *stream,long offset,int whence); 功能:设置流的偏移量的标识 参数:stream:文件流指针offset:偏移量>0 向后偏移<0 向前偏移whence:标识SEEK_SET:文件开头SEEK_CUR:当前位置SEEK_END:文件末尾 返回值:成功返回0失败返回-1
-
ftell
原型:long ftell(FILE *stream); 功能:获得流的偏移量 参数:stream:文件流指针 返回值:成功返回流的偏移量
-
rewind
原型:void rewind(FILE *stream); 功能:将流重新定位到开头
练习1:从终端输入一个文件名,获得文件的长度
#include<stdio.h>int main(void){FILE *fp = NULL;long len = 0;char filename[32] = {0};int cnt = 0;scanf("%s",filename);fp = fopen(filename,"r");if(NULL == fp){perror("fail to fopen");return -1;}fseek(fp,0,SEEK_END);len = ftell(fp);printf("len = %ld\n",len);return 0; }
练习2:从bmp文件中读取图片的宽度和高度
#include<stdio.h>int main(void){FILE *fp = NULL;int width = 0;int height = 0;fp = fopen("1.bmp","r");if(NULL == fp){perror("fail to fopen");return -1;}fseek(fp,18,SEEK_SET);fread(&width, 4, 1, fp);fread(&height, 4, 1, fp);printf("width = %d, height = %d\n", width, height);fclose(fp);return 0;}
-
2.文件IO
1.概念:
- 标准IO是有缓存的IO,文件IO没有缓存,适合于通信,硬件设备操作
- 标准IO是库函数,文件IO是系统调用
2.系统调用和库函数
- 系统调用:是Linux内核中的代码,只能在Linux中使用
- 库函数:是对系统调用的封装,可以在不同的操作系统中安装并使用,库函数最终还是要调用系统调用完成对应功能
3.文件IO函数接口
-
函数接口
标准IO 文件IO fopen open fclose close fgetc/fputc read/write fgets/fputs fscanf/fprintf fread/fwrite fseek/ftell/rewind lseek
-
文件打开
原型: 功能:打开文件获得操作文件的文件描述符 参数:pathname:要打开的文件路径flags:打开文件的标志,必须包含三者之一O_RDONLYO_WRONLYO_RDWRO_CREAT 文件不存在创建O_TRUNC 文件存在截断为0O_APPEND 追加O_EXCL 文件存在报错 返回值:成功返回新文件描述符失败返回-1
- 有三个特殊的文件描述符:标准输入(0),标准输出(1),标准错误(2)
- 文件描述符特点
- 取未被占用的最小的非负整数
- 文件描述符有上限,到达上限后再打开会报错误
-
关闭文件描述符
原型:int close(int fd); 功能: 关闭文件描述符
-
标准IO对应文件IO的打开方式
标准IO | 文件IO |
---|---|
r | O_RDONLY |
r+ | O_RDWR |
w | O_WRONLY |O_CREAT |O_TRUNC , 0664 |
w+ | O_RDWR | O_CREAT | O_TRUNC , 0664 |
a | O_WRONLY |O_APPEND | O_CREAT , 0664 |
a+ | O_RDWR | O_APPEND | O_CREAT , 0664 |
-
文件IO读写
-
write
原型:ssize_t write(int fd, const void *buf, size_t count); 功能: 向文件描述符中写入buf指向的count个字节的数据 参数: fd:文件描述符 buf:要写入的数据空间首地址 count:要写入的字节数 返回值: 成功返回实际写入的字节数 失败返回-1
-
习题
1.利用fread和fwrite实现图片的拷贝
代码实现:
#include<stdio.h>int main(void){FILE *fp = NULL;FILE *fp1 = NULL;char filename[100];char filename1[100];char tmpbuff[4096] = {0};size_t nret = 0;printf("请输入源图片名:");scanf("%s",filename);fp = fopen(filename,"r");if(fp == NULL){perror("fail to fopen");return -1;}printf("请输入目标图片名:");scanf("%s",filename1);fp1 = fopen(filename1,"w");if(fp1 == NULL){perror("fail to fopen");return -1;}while(1){nret = fread(tmpbuff, 1, sizeof(tmpbuff), fp);if(nret == 0){break;}fwrite(tmpbuff,1,nret,fp1);}fclose(fp);fclose(fp1);return 0;
}
2.统计一个文件中出现最多字符是哪个,并显示出现了多少次
代码实现:
#include<stdio.h>
#include<stdlib.h>typedef struct linknode{char data;int count;struct linknode *next;
} node;int main(){FILE *fp = NULL;char filename[100] = {0};char ch;node *head = NULL;node *current = NULL;node *tmp = NULL;int max = 0;printf("请输入要扫描的文件:");scanf("%s", filename);fp = fopen(filename,"r");if(fp == NULL){printf("无法打开文件!\n");return 1;}while(1){ch = fgetc(fp);if(ch == EOF) {break;}current = head;while(current != NULL){if(current->data == ch){current->count++;break;}current = current->next;}if(current == NULL){tmp = malloc(sizeof(node));if(tmp == NULL){perror("fail to malloc");return -1;}tmp->data = ch;tmp->count = 1;tmp->next = head;head = tmp;}}current = head;while(current != NULL){if(current->count > max){max = current->count;tmp = current;}current = current->next;}printf("出现次数最多的字符为:%c\n出现了%d次\n",tmp->data,tmp->count);while(head != NULL){tmp = head;head = head->next;free(tmp);}fclose(fp);return 0;
}