处理其他资源之三
int_range.h
#ifndef _INT_RANGE_H_
#define _INT_RANGE_H_
#include "file_reader.h"
#include "buffer.h"
#include "limits.h"
#include "string.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
FileAcessorContext base;
long size;
}FileSizeGetterContext;
typedef enum {
ERR_CAT_OK,
ERR_CAT_FILE,
ERR_CAT_MEMORY
}IntRangeError;
typedef struct {
const char * const pFname;
int errorCatgory;
}Context;
typedef struct {
BufferContext base;
Context *pAppCtx;
}MyBufferContext;
typedef struct {
FileAcessorContext base;
MyBufferContext *pBufCtx;
}MyFileAccessorContext;
IntRangeError int_range(const char * const pFname);
static long file_size(const char * const pFname);
static void size_reader(FileAcessorContext *p, FILE *fp);
static long buffer_allocate(long size, Context *pAppCtx);
static void file_error(Context *pCtx);
static void buffer_error(Context *pCtx);
static void do_with_buffer(BufferContext *p);
static void reader(FileAcessorContext *p, FILE *fp);
static void writer(FileAcessorContext *p, FILE *fp);
static int range_processor(char *buf, size_t size);
#ifdef __cplusplus
}
#endif
#endif
int_range.c
#include "int_range.h"
static long file_size(const char * const pFname){
FileSizeGetterContext ctx = {{pFname, "r", size_reader}, 0};
if(!access_file(&ctx.base)){
return -1;
}
return ctx.size + 1; //需要为内存多分配一个字节
}
static void size_reader(FileAcessorContext *p, FILE *fp){
FileSizeGetterContext *pThis = (FileSizeGetterContext *)p;
pThis->size = -1;
if(fseek(fp, 0, SEEK_END) == 0)
pThis->size = ftell(fp);
}
static long buffer_allocate(long size, Context *pAppCtx){
MyBufferContext bufCtx = {{NULL, size, do_with_buffer}, pAppCtx};
if(!buffer(&bufCtx.base)){
return -1;
}
return size;
}
IntRangeError int_range(const char * const pFname){
Context ctx = {pFname, ERR_CAT_OK};
long size = file_size(pFname);
if(size == -1){
file_error(&ctx);
return ctx.errorCatgory;
}
long buffer_size = buffer_allocate(size, &ctx);
if(buffer_size == -1){
buffer_error(&ctx);
return ctx.errorCatgory;
}
}
static void file_error(Context *pCtx){
printf("Failed to open File: %s\n", pCtx->pFname);
pCtx->errorCatgory = ERR_CAT_FILE;
}
static void buffer_error(Context *pCtx){
printf("Failed to malloc memory\n");
pCtx->errorCatgory = ERR_CAT_MEMORY;
}
static void do_with_buffer(BufferContext *p) {
MyBufferContext *pBufCtx = (MyBufferContext *)p;
MyFileAccessorContext readFileCtx = {{pBufCtx->pAppCtx->pFname, "rb", reader}, pBufCtx};
if(!access_file(&readFileCtx.base)){
file_error(pBufCtx->pAppCtx);
return;
}
int value = range_processor(p->pBuf, p->size);
printf("value is %d\n", value);
MyFileAccessorContext writeFileCtx = {{pBufCtx->pAppCtx->pFname, "wb", writer}, pBufCtx};
if(!access_file(&readFileCtx.base)){
file_error(pBufCtx->pAppCtx);
return;
}
}
static void reader(FileAcessorContext *p, FILE *fp){
MyFileAccessorContext *pFileCtx = (MyFileAccessorContext *)p;
MyBufferContext *pBufCtx = pFileCtx->pBufCtx;
if(fgets(pBufCtx->base.pBuf, pBufCtx->base.size, fp) == NULL){
file_error(pBufCtx->pAppCtx);
}
}
static void writer(FileAcessorContext *p, FILE *fp){
MyFileAccessorContext *pFileCtx = (MyFileAccessorContext *)p;
MyBufferContext *pBufCtx = pFileCtx->pBufCtx;
if(fputs(pBufCtx->base.pBuf, fp)){
file_error(pBufCtx->pAppCtx);
}
}
static int range_processor(char *buf, size_t size){
int min = INT_MAX;
int max = INT_MIN;
char *temp = strtok(buf, " ");
while(temp){
int value = atoi(temp);
min = min > value ? value : min;
max = max < value ? value : max;
temp = strtok(NULL, " ");
}
return max - min;
}
range_test.c
#include "int_range.h"
int main(int argc, char const *argv[])
{
int_range("nums.txt");
return 0;
}
以上是从nums.txt中读取一行数字,并将这些数值的范围值返回。
这个代码是可以复用的。只要将range_processor换成其他的功能就可以做另外的处理了。

浙公网安备 33010602011771号