处理其他资源

test.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

int main(int argc, char const *argv[])
{
    char *buf = NULL;
    int flen = 0;
    int min = INT_MAX;
    int max = INT_MIN;
    int ret = 0;

    FILE *fp = fopen("nums.txt", "r");
    if(fp == NULL){
        printf("Failed to open file\n");
        exit(0);
    }

    fseek(fp, 0, SEEK_END);
    flen = ftell(fp);
    buf = malloc(flen+1);
    buf[flen] = '\0';
    if(buf == NULL)
    {
        printf("No memory\n");
        fclose(fp);
        exit(0);
    }
    fseek(fp,0L,SEEK_SET);
    while(fgets(buf, flen+1, fp) != NULL)
    {
        if(buf[0] == '\n') 
        {
            printf("empty line\n");
            free(buf);
            fclose(fp);
            exit(0);
        }
        char *temp = strtok(buf, " ");
        while(temp){
            int value = atoi(temp);
            min = min > value ? value : min;
            max = max < value ? value : max;
            temp = strtok(NULL, " ");
        }
    }
    free(buf);
    fclose(fp);

    ret = max - min;
    printf("ret is %d\n", ret);
    
    return ret;
}
 
以上代码是从一个txt文件中读取第一行,并返回这一行数字的范围值。
这段代码 函数功能堆砌在一起,函数功能不单一,可阅读性差。
资源管理不清晰(文件打开与关闭、内存分配与释放)。
 
那么我分成两个文件:
range.h
#ifndef _RANGE_H_
#define _RANGE_H_

#ifdef __cplusplus
extern "C" {
#endif

int range(FILE *fp);

#ifdef __cplusplus
}
#endif

#endif
 
range.c
 
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>

int range(FILE *fp){
    int min = INT_MAX;
    int max = INT_MIN;

    fseek(fp, 0, SEEK_END);
    int flen = ftell(fp);
    char *buf = malloc(flen+1);
    buf[flen] = '\0';
    fseek(fp, 0, SEEK_SET);

    while((fgets(buf, flen, fp)) != NULL){
        if(buf[0] == '\r'){
            printf("empty line\n");
            free(buf);
            fclose(fp);
            exit(0);
        }
        char *temp = strtok(buf," ");
        while(temp != NULL){
            int value = atoi(temp);
            min = min > value ? value : min;
            max = max < value ? value : max;
            temp = strtok(NULL," ");
        }
    }
    return max - min;
}
 
range_test.c
#include <stdio.h>
#include <stdlib.h>
#include "range.h"

int main(int argc, char const *argv[])
{
    FILE *fp = fopen("nums.txt", "r");
    if(fp == NULL){
        printf("Failed to open file\n");
        exit(0);
    }

    int ret = range(fp);
    printf("ret is %d\n", ret);

    fclose(fp);

    return 0;
}
 
这样子,在main 函数里,打开文件 ---- 获取取值范围 ---- 关闭文件。
看起来很清晰,但是在range.c有不得不写的释放资源与关闭文件的地方。
因为在获取取值范围时,需要分配内存,内存一旦分配失败,必须释放内存,同时还要关闭文件,不然会造成内存泄漏。
撇开以上的问题不说,还有一个问题 ---- 在main函数里应该只有一个语句才合适,那就是 range("nums.txt");
至于怎么去打开、关闭文件,怎么分配、释放内存,应该写出阅读性更好的代码。
那么像以下这样子:
range.h
#ifndef _RANGE_H_
#define _RANGE_H_

#ifdef __cplusplus
extern "C" {
#endif

int range(const char* pFname);

#ifdef __cplusplus
}
#endif

#endif
 
range.c
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdlib.h>
#include "file_reader.h"
#include "range.h"

int range_processor(FILE *fp){
    int min = INT_MAX;
    int max = INT_MIN;

    fseek(fp, 0, SEEK_END);
    int flen = ftell(fp);
    char *buf = malloc(flen+1);
    buf[flen] = '\0';
    fseek(fp, 0, SEEK_SET);

    while((fgets(buf, flen, fp)) != NULL){
        if(buf[0] == '\r'){
            printf("empty line\n");
            free(buf);
            fclose(fp);
            exit(0);
        }
        char *temp = strtok(buf," ");
        while(temp != NULL){
            int value = atoi(temp);
            min = min > value ? value : min;
            max = max < value ? value : max;
            temp = strtok(NULL," ");
        }
    }
    return max - min;
}

int range(const char* pFname){
    return read_file(pFname, range_processor);
}
 
file_reader.h
#ifndef _FILE_READER_H_
#define _FILE_READER_H_

#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

int read_file(const char *pFname, int (* const processor)(FILE *fp));

#ifdef __cplusplus
}
#endif

#endif
 
file_reader.c
#include <stdio.h>
#include "file_reader.h"

int read_file(const char *pFname, int (* const processor)(FILE *fp)){
    FILE *fp = fopen(pFname, "r");
    if(fp == NULL){
        return -1;
    }
    
    int ret = processor(fp);

    fclose(fp);

    return ret;
}
 
range_test.c
#include <stdio.h>
#include <stdlib.h>
#include "range.h"

int main(int argc, char const *argv[])
{
    int ret = range("nums.txt");
    printf("ret is %d\n", ret);

    return 0;
}
 
如上: 代码的可阅读性明显变强了。
应用程序main —— 从nums.txt 获取一行数值的范围值。
range.c —— 从打开的文件中获取一行数值的范围值。、
file_reader.c —— 文件的打开、操作 以及 关闭。
但是range.c中仍然存在文件打开、关闭 以及 内存分配、释放的代码。
文件的打开、关闭 以及 内存的分配、释放应该一一对应,不然遗忘一两处将造成内存泄漏。
所以还要继续优化这个代码。
 
 

猜你喜欢

转载自www.cnblogs.com/vonyoven/p/12012782.html