模板方法模式之三
上一节file_reader.c中:
int ret = processor(fp);
返回的处理结果是int型的值,如果需要返回非int值怎么办?
typedef struct FileReaderContext{
const char *pFname;
void (* const processor)(struct FileReaderContext *pThis, FILE *fp);
}FileReaderContext;
如上,processor是文件的处理接口。这样processor就可以返回非int型了。
至于真正的文件内容处理的返回值可以通过继承来实现。
typedef struct MyFileReaderContext
{
FileReaderContext base;
float result;
}MyFileReaderContext;
以上result就保存真正的文件内容处理的返回值。
range.h
#ifndef _RANGE_H_
#define _RANGE_H_
#include "file_reader.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct MyFileReaderContext
{
FileReaderContext base;
float result;
}MyFileReaderContext;
float range(const char *pFname);
float sum(const char *pFname);
static float range_processor(FILE *fp);
static float sum_processor(FILE *fp);
static void calc_range(FileReaderContext *pThis, FILE *fp);
static void calc_sum(FileReaderContext *pThis, FILE *fp);
#ifdef __cplusplus
}
#endif
#endif
range.c
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include "file_reader.h"
#include "range.h"
static float range_processor(FILE *fp){
float min = INT_MAX;
float max = INT_MIN;
char buf[256] = {0};
while((fgets(buf, sizeof(buf), fp)) != NULL){
if(buf[0] == '\r'){
printf("empty line\n");
return -1;
}
char *temp = strtok(buf," ");
while(temp != NULL){
float value = atof(temp);
min = min > value ? value : min;
max = max < value ? value : max;
temp = strtok(NULL," ");
}
}
return max - min;
}
static float sum_processor(FILE *fp){
float sum = 0;
char buf[256] = {0};
while((fgets(buf, sizeof(buf), fp)) != NULL){
if(buf[0] == '\r'){
printf("empty line\n");
return -1;
}
char *temp = strtok(buf," ");
while(temp != NULL){
float value = atof(temp);
sum += value;
temp = strtok(NULL," ");
}
}
return sum;
}
static void calc_range(FileReaderContext *pThis, FILE *fp){
MyFileReaderContext *pCtx = (MyFileReaderContext *)pThis;
pCtx->result = range_processor(fp);
}
static void calc_sum(FileReaderContext *pThis, FILE *fp){
MyFileReaderContext *pCtx = (MyFileReaderContext *)pThis;
pCtx->result = sum_processor(fp);
}
float range(const char *pFname){
MyFileReaderContext ctx = {{pFname, calc_range}, 0.0};
if(read_file(&ctx.base) != 0){
printf("Cannot open file '%s'\n", pFname);
}
return ctx.result;
}
float sum(const char *pFname){
MyFileReaderContext ctx = {{pFname, calc_sum}, 0.0};
if(read_file(&ctx.base) != 0){
printf("Cannot open file '%s'\n", pFname);
}
return ctx.result;
}
file_reader.h
#ifndef _FILE_READER_H_
#define _FILE_READER_H_
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct FileReaderContext{
const char *pFname;
void (* const processor)(struct FileReaderContext *pThis, FILE *fp);
}FileReaderContext;
int read_file(FileReaderContext *pCtx);
#ifdef __cplusplus
}
#endif
#endif
file_reader.c
#include "file_reader.h"
int read_file(FileReaderContext *pCtx){
FILE *fp = fopen(pCtx->pFname, "r");
if(fp == NULL)
return -1;
pCtx->processor(pCtx, fp);
fclose(fp);
return 0;
}
range_test.c
#include <stdio.h>
#include "range.h"
int main(int argc, char const *argv[])
{
float ret = range("nums.txt");
printf("ret is %f\n", ret);
ret = sum("nums.txt");
printf("sum is %f\n", ret);
return 0;
}
除了使用继承方法,本节没有太多意义。

浙公网安备 33010602011771号