用C語言實現解析簡單設定檔的小工具

來源:互聯網
上載者:User

本文介紹作者寫的一個小工具,簡單的代碼中包含了C語言對字串的處理技巧,對文字檔的簡單解析,二進位檔案的資料複製的方法,以及格式化輸出文字檔的樣本。

工具的輸入是如下內容的設定檔:

;資源管理員配置指令碼;以行為單位,每行不能超過255個字元;空行和以;開頭的注釋行會被忽略掉;每行都關聯一個資源檔,資源序號從0開始,依次遞增.\img\img128x128.bin.\snd\start.wav.\img\sheis1.bin.\snd\balloon.wav.\img\sheis2.bin

工具的原始碼貼在這裡:

#include <ctype.h>#include <string.h>#include <stdlib.h>#include <stdio.h>/* 定義相關檔案名稱 */#define CONFIG_FILE_NAME        ("config.txt")#define RESPAK_FILE_NAME        ("resmm.bin")#define ADDRS_C_FILE_NAME       ("resmm_addrs.c")/* 定義配置行最大的字元數 */#define LINE_CHARS      (255)/* 定義複製檔案資料時的緩衝區大小 */#define BUF_SIZE        (8 * 1024)/* 從配置行提取檔案名稱 */static char* extract_file_name(const char* line, char* file_name){    /* 過濾配置行左邊的空格符 */    while(isspace(*line++)){};    line--;    /* 忽略空行和注釋行 */    if((*line == '\0') || (*line == ';'))        return NULL;    /* 提取檔案名稱,並去掉右邊的空格符 */    strcpy(file_name, line);    {        char* p = file_name + strlen(file_name) - 1;        while(isspace(*p--)){};        p++;        p++;        *p = '\0';    }    return file_name;}/* 掃描有效檔案數 */static int scan_file_count(FILE* cf){    char line[LINE_CHARS + 1];    char file_name[LINE_CHARS + 1];    int count = 0;    while(!feof(cf))    {        fgets(line, LINE_CHARS, cf);        if(extract_file_name(line, file_name) != NULL)            count++;    }    return count;}/* 複製檔案資料 */static size_t copy_file_datas(FILE* pf, FILE* rf){    unsigned char buf[BUF_SIZE];    size_t total = 0;    size_t len;    do{        len = fread(buf, sizeof(unsigned char), BUF_SIZE, rf);        fwrite(buf, sizeof(unsigned char), len, pf);        total += len;    }while(len == BUF_SIZE);    return total;}/* 主函數 */int main(int argc, char* argv[]){    FILE* cf;    FILE* pf;    FILE* rf;    int count;    size_t* lens;    size_t len;    unsigned int addr;    char line[LINE_CHARS + 1];    char file_name[LINE_CHARS + 1];    int i;    /* 開啟設定檔,並掃描有效檔案數 */    if((cf = fopen(CONFIG_FILE_NAME, "rt")) == NULL)    {        printf("Can\'t open %s!\n", CONFIG_FILE_NAME);        return -1;    }    count = scan_file_count(cf);    fseek(cf, 0L, SEEK_SET);    /* 開啟資源套件檔案 */    if((pf = fopen(RESPAK_FILE_NAME, "wb")) == NULL)    {        printf("Can\'t create %s!\n", RESPAK_FILE_NAME);        fclose(cf);        return -1;    }    /* 複製打包資源檔,並統計其大小 */    if((lens = (size_t*)malloc(sizeof(size_t) * count)) == NULL)    {        printf("No enough memory!\n");        fclose(pf);        fclose(cf);        return -1;    }    i = 0;    while(!feof(cf))    {        fgets(line, LINE_CHARS, cf);        if(extract_file_name(line, file_name) != NULL)        {            if((rf = fopen(file_name, "rb")) == NULL)            {                printf("Can\'t open %s!\n", file_name);                fclose(pf);                fclose(cf);                return -1;            }            if((len = copy_file_datas(pf, rf)) == 0)            {                printf("File %s is empty!\n", file_name);                fclose(pf);                fclose(cf);                return -1;            }            lens[i++] = len;            fclose(rf);        }    }    fclose(pf);    fclose(cf);    /* 開啟地址描述的C語言源檔案 */    if((cf = fopen(ADDRS_C_FILE_NAME, "wt")) == NULL)    {        printf("Can\'t open %s!\n", ADDRS_C_FILE_NAME);        return -1;    }    /* 把各個資源的地址和長度資訊寫入C語言數組 */    fprintf(cf, "#define RES_COUNT\t(%d)\n\n", count);    fprintf(cf, "static const INT32U addrs[RES_COUNT] = \n{\n");    addr = 0;    for(i = 0; i < count; i++)    {        fprintf(cf, "\t\t0x%08x,\n", addr);        addr += lens[i];    }    fprintf(cf, "};\n\n");    fprintf(cf, "static const INT32U lens[RES_COUNT] = \n{\n");    for(i = 0; i < count; i++)        fprintf(cf, "\t\t0x%08x,\n", lens[i]);    fprintf(cf, "};");    fclose(cf);    free(lens);    return 0;}

格式化輸出的文字檔是這樣的:

#define RES_COUNT(5)static const INT32U addrs[RES_COUNT] = {0x00000000,0x00008000,0x0000889a,0x0001089a,0x0001219a,};static const INT32U lens[RES_COUNT] = {0x00008000,0x0000089a,0x00008000,0x00001900,0x00008000,};

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.