第3章 文件I/O(8)_贯穿案例:构建标准IO函数库
9. 贯穿案例:构建标准IO函数库
//mstdio.h
#ifndef __MSTDIO_H__
#define __MSTDIO_H__ #include <unistd.h> #define MEOF -1 //定义文件末尾标志 //文件读写模式
enum mode{READ, WRITE, APPEND}; //MFILE结构体
typedef struct
{
int _fd;
char* _buffer; //缓冲区
char* _nextc; //下一个字符
int _mode; //读写模式
off_t _left; //剩余多少字节(对于读表示缓冲区中未读的
//字节数对于写,表示缓冲区还剩的空闲空间)
}MFILE, *PMFILE; extern MFILE* mfopen(const char* const pathname, const char* const mode);
extern int mfclose(MFILE* fp);
extern void mfflush(MFILE* fp);
extern MFILE* mfdopen(int fd, const char* const mode);
extern int mfgetc(MFILE* fp);
extern int mfputc(int character, MFILE* fp);
extern int mungetc(int character, MFILE* fp);
extern char* mfgets(char* buff, int size, MFILE* fp);
extern int mfputs(char* buff, MFILE* fp);
extern size_t mfread(void* buff, size_t size, size_t counter, MFILE* fp);
extern size_t mfwrite(void* buff, size_t size, size_t counter, MFILE* fp); #endif
//mstdio.c
#include "mstdio.h"
#include <assert.h>
#include <string.h>
#include <fcntl.h>
#include <malloc.h> #define BUFFER_LEN 1024 MFILE* mfopen(const char* const pathname, const char* const mode)
{
int fd; if(!strcmp(mode, "r")){
fd = open(pathname, O_RDONLY);
}else if(!strcmp(mode, "w")){
fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC, );
}else if(!strcmp(mode, "a")){
fd = open(pathname, O_WRONLY | O_CREAT | O_APPEND, );
}else{
return NULL;
} if (fd < ) return NULL; return mfdopen(fd, mode);
} int mfclose(MFILE* fp)
{
mfflush(fp); //先刷新缓存 int ret = close(fp->_fd); free(fp->_buffer);
free(fp); return ret;
} void mfflush(MFILE* fp)
{
if(fp->_mode = READ){
fp->_nextc = fp->_buffer;
fp->_left = ;
}else{ //WRITE or APPEND
write(fp->_fd, fp->_buffer, (BUFFER_LEN - fp->_left)); fp->_nextc = fp->_buffer;
fp->_left = BUFFER_LEN;
} } MFILE* mfdopen(int fd, const char* const mode)
{
MFILE* fp = (MFILE*)malloc(sizeof(MFILE));
assert( fp != NULL); //断言fp存在 fp->_buffer = (char*)malloc(BUFFER_LEN); //创建缓冲区
assert(fp->_buffer != NULL); fp->_fd = fd;
fp->_nextc = fp->_buffer; //初始化,指向缓冲区开始处 if(!strcmp(mode, "r")){
fp->_mode = READ;
fp->_left = ; //缓冲区剩余0字节未读取,即全部读完。
} if(!strcmp(mode, "w")){
fp->_mode = WRITE;
fp->_left = BUFFER_LEN; //缓冲区剩BUFFER_LEN未写,即空的
} if(!strcmp(mode, "a")){
fp->_mode = APPEND;
fp->_left = BUFFER_LEN;
} return fp;
} int mfgetc(MFILE* fp)
{
assert(fp->_mode == READ); //只允许读操作 //当缓存中的数据己读取完毕,先从文件中读取一批新的数据
//存入缓存中
if (fp->_left == ){
ssize_t size = read(fp->_fd, fp->_buffer, BUFFER_LEN); assert( size >= ); if(size == ) return MEOF; fp->_nextc = fp->_buffer;
fp->_left = size;
} char c = *(fp->_nextc);
fp->_nextc++;
fp->_left--; return c;
} int mfputc(int character, MFILE* fp)
{
assert(fp->_mode == WRITE || fp->_mode == APPEND); //若缓存己满,则先将缓存中的数据写入到文件中
if(fp->_left == ){
if(write(fp->_fd, fp->_buffer, BUFFER_LEN) != BUFFER_LEN){
return ;
} fp->_nextc = fp->_buffer;
fp->_left = BUFFER_LEN;
} *(fp->_nextc) = (char)character;
fp->_nextc++;
fp->_left--; return ; //返回成功写入的字符个数
} int mungetc(int character, MFILE* fp)
{
int ret = ; return ret;
} char* mfgets(char* buff, int size, MFILE* fp)
{
char* ret = NULL; return ret;
} int mfputs(char* buff, MFILE* fp)
{
int ret = ; return ret;
} size_t mfread(void* buff, size_t size, size_t counter, MFILE* fp)
{
size_t ret = ; return ret;
} size_t mfwrite(void* buff, size_t size, size_t counter, MFILE* fp)
{
size_t ret = ; return ret;
}
//mstdio_test.c
#include "mstdio.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> int main(int argc, char* argv[])
{ MFILE* fp1 = mfopen("/etc/passwd", "r");
assert(fp1 != NULL); MFILE* fp2 = mfopen("mypasswd", "w");
assert( fp2 != NULL); char c;
while((c=mfgetc(fp1)) != MEOF){
mfputc(c, fp2);
} mfclose(fp1);
mfclose(fp2); return ;
}
第3章 文件I/O(8)_贯穿案例:构建标准IO函数库的更多相关文章
- 第8章 信号(6)_贯穿案例2:mini shell(3)
4. 贯穿案例2:mini shell(3) (1)之前存在问题 ①刚运行时,mshell作为前台进程.运行的其他命令会被加入新的进程组,并且调用tcsetpgrp将这个进程组设置为前台进程组,因此m ...
- 第7章 进程关系(5)_贯穿案例2:mini shell(2)
5. 贯穿案例2:mini shell(2) (1)己经完成的功能:pwd.cd.exit命令 (2)阶段性目标: ①env.export.echo及其他命令 ②标准输入.输出重定向"> ...
- Linux C 文件操作,系统调用 -- open()、read() 和 标准I/O库 -- fopen()、fread()
函数汇总: open().write().read().close() fopen().fwrite().fread().fclose() 一.什么是文件 在讲述文件操作之前,我们首先要知道什么是文件 ...
- 第4章 文件和目录(5)_贯穿案例2:mini shell(1)
6. 贯穿案例2:mini shell(1) [阶段性任务]实现cd.pwd和quit命令 //job.h #ifndef __JOB_H__ #define __JOB_H__ //接收命令行参数 ...
- 九、文件IO——案例构建标准库
例子如下: mystdio.h #ifndef __MYSTDIO_H__ #define __MYSTDIO_H__ #include <sys/types.h> #define MYE ...
- 【C语言入门教程】5.6 函数库和文件
函数库是为代码复用建立的,将同一类型,需要在不同的程序里使用的函数放置在一起,就组成了一个函数库.如 C 语言的标准库,它集合了开发者常用的函数.开发者自行编写的函数也可以组成函数库,通常称之为自定义 ...
- makefile笔记10 - makefile 函数库文件
函数库文件也就是对 Object 文件(程序编译的中间文件)的打包文件.在 Unix 下,一般是由命令"ar"来完成打包工作. 一.函数库文件的成员 一个函数库文件由多个文件组成. ...
- 循环 与 分支语句 和 字符函数库cctype 文件简单处理
循环 for循环 while循环 do while循环 通常,入口条件循环比出口条件循环好,因为循环开始前对条件进行检查 c++11基于范围的for循环 对数组(或容器类,如:vector和a ...
- 第3章 文件I/O(7)_高级文件操作:存储映射
8. 高级文件操作:存储映射 (1)概念: 存储映射是一个磁盘文件与存储空间的一个缓存相映射,对缓存数据的读写就相应的完成了文件的读写. (2)mmap和munmap函数 头文件 #include&l ...
随机推荐
- Iview同步异步验证
直接上代码了: html: <Form ref="termForm" :model="currentData" :rules="ruleTerm ...
- Redis 学习第一课:安装Linux Redis(Ubantu)
对于分布式缓存,之前公司项目中只使用了MemCached,使用比较方便,有现成的C#版本组件. 如今用Redis的公司有很多,所以打算了解一下Redis. Redis的官网地址:http://redi ...
- ROS功能包- rrt_exploration
一种基于RRT实现的多机器人地图探测算法的ROS软件包. 它还具有使用图像处理提取边界点.基于图像的边界检测等功能. 适用版本:indigo.jade.kinetic.lunar. 注意事项:官网文档 ...
- fork调用实验-缓冲区相关
先看下面一段代码: #include <unistd.h> #include <stdio.h> ; char buf[] = "a write to stdout\ ...
- 在word文档里提取出所有的邮箱地址
怎样在word文档里提取出所有的邮箱地址 文档内容太多,邮箱也有很多,一个个复制粘贴太浪费时间,怎样把这些邮箱简单的提取出来 答案:用查找功能. 查找目标:[A-z,0-9]{1,}\@[A-z,0 ...
- 利用Fierce2查询子域名
http://pnig0s1992.blog.51cto.com/393390/368428 安装方法引用Mickey的: 1.Mickey@pentestbox:/pentest/enumerati ...
- Spring的事件发布机制
一:Spring的事件发布 ApplicationContext提供了针对Bean的事件传播功能,其中的主角是publishEvent()方法,通过这个方法可以将事件通知给系统内的监听器(需实现App ...
- 51Nod 1002:数塔取数问题(DP)
1002 数塔取数问题 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值. 每 ...
- ssh 免 密码登录另一台机器 和 secureCRT的乱码问题
PS: 就是你把密钥生成好以后,放入B机器中,再登录的时候就已经有了所以就不用验证了 ========================================================= ...
- MySQL--Alter Table注意事项
======================================================================== ALTER TABLE 和FLUSH TABLE导致的 ...