【编程小练习】简单错误记录

【题目】

开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1、 记录最多8条错误记录,循环记录,对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加;
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。
Input:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
如:E:\V1R2\product\fpgadrive.c 1325
Output:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开。
如:fpgadrive.c 1325 1

【实现】

以下给出作者的解法(思路类似《一则表驱动法的应用实例》):

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


#define ERR_NUM                  8 //允许共存的错误数目
#define ERR_NAME_LEN             sizeof("123456789ABCDE.c 4294967295 4294967295")
#define FILE_NAME_LEN            256 //假定文件路径最大长度为256字节
#define TRIM_FILENAME_LEN        16
typedef struct {
    char szFileName[FILE_NAME_LEN];
    unsigned int dwLineNo;
    unsigned int dwOccurs; 
}T_ERR_REC;

//gErrorMap按新旧次序环形记录ERR_NUM条错误记录
static char gErrorMap[ERR_NUM][ERR_NAME_LEN] = {{0}};

//gLatestErrIndex记录gErrorMap第一维最新错误记录的下标,
//该下标+1并对ERR_NUM取余后对应的元素为最旧的错误记录,即
//Oldest = (Latest + 1) mod ERR_NUM.
static unsigned int gLatestErrIndex = ERR_NUM-1;

static char *GetFileBasename(char *pszFileName) {
     return strrchr(pszFileName, '\\') + 1; //也可考虑兼容Unix斜杠
}
static char *GetTrimmedFileName(char *pszFileName) {
    unsigned int dwNameLen = strlen(pszFileName);
    if(dwNameLen > TRIM_FILENAME_LEN)
        return &pszFileName[dwNameLen-TRIM_FILENAME_LEN];
    else
        return &pszFileName[0];
}
static void InsertErrorRecord(char *pszMapEntry, T_ERR_REC *ptErrRec) {
    memset(pszMapEntry, 0, ERR_NAME_LEN); //为求通用,对新增条目也先清零
    sprintf(pszMapEntry, "%s %u %u",
        GetTrimmedFileName(GetFileBasename(ptErrRec->szFileName)),
        ptErrRec->dwLineNo, ptErrRec->dwOccurs);
}
void ShowErrorRecord(void) {
    printf("Current Error Record:\n");
    unsigned int dwRecIdx = 0;
    for(; dwRecIdx < ERR_NUM && '\0' != gErrorMap[dwRecIdx][0]; dwRecIdx++) {
        printf("  [%u]: %s\n", dwRecIdx, gErrorMap[dwRecIdx]);
    }
}
int CreateErrorRecord(char *pszErrorInfo){
    if(NULL == pszErrorInfo || '\0' == *pszErrorInfo)
       return -1;

    //解析错误信息里的文件名和行号
    T_ERR_REC tErrRec = {/*.szFileName=*/{0}, /*.dwLineNo=*/0, /*.dwOccurs=*/1};
    if(sscanf(pszErrorInfo, "%s %u", tErrRec.szFileName, &tErrRec.dwLineNo) != 2)
        return -1;

    unsigned int dwRecIdx = 0, bIsInErrorRecord = 0;
    char *pszBaseName = GetFileBasename(tErrRec.szFileName);
    for(; dwRecIdx < ERR_NUM && '\0' != gErrorMap[dwRecIdx][0]; dwRecIdx++) {
        //相同的错误记录
        if(!strncmp(pszBaseName, gErrorMap[dwRecIdx], strlen(pszBaseName))) {
            unsigned int dwSavedOccurs = strtol((strrchr(gErrorMap[dwRecIdx], ' ')+1), NULL, 10);
            tErrRec.dwOccurs += dwSavedOccurs;
            bIsInErrorRecord = 1;
            break;
        }
    }

    if(bIsInErrorRecord) {
        InsertErrorRecord(gErrorMap[dwRecIdx], &tErrRec);
    } else {
        gLatestErrIndex = (gLatestErrIndex+1)%ERR_NUM;
        InsertErrorRecord(gErrorMap[gLatestErrIndex], &tErrRec);
    }

    return 0;
}

int main(void) {
    CreateErrorRecord("E:\\V1R2\\product\\fpgadrive.c 1"); CreateErrorRecord("E:\\V1R2\\fpgadrive_bak.c 2");
    CreateErrorRecord("E:\\V1R2\\fpgadrive_pdt.c 3"); CreateErrorRecord("E:\\fpgadrive_fpgpdt.c 4");
    CreateErrorRecord("E:\\fpga.c 5"); CreateErrorRecord("E:\\V1R2\\123456789ABCDEFG.c 6");
    CreateErrorRecord("E:\\V1R2\\product\\fpgadrive2.c 7"); CreateErrorRecord("E:\\V1R2\\fpgadrive_bak2.c 8");
    CreateErrorRecord("E:\\fpga.c 1"); ShowErrorRecord(); //相同错误记录
    CreateErrorRecord("E:\\fpga123456789AB.c 10"); ShowErrorRecord(); //文件名超过16个字符
    //while(1);
    return 0;
}

运行效果如下:

Current Error Record:
  [0]: fpgadrive.c 1 1
  [1]: fpgadrive_bak.c 2 1
  [2]: fpgadrive_pdt.c 3 1
  [3]: gadrive_fpgpdt.c 4 1
  [4]: fpga.c 1 2
  [5]: 3456789ABCDEFG.c 6 1
  [6]: fpgadrive2.c 7 1
  [7]: fpgadrive_bak2.c 8 1
Current Error Record:
  [0]: pga123456789AB.c 10 1
  [1]: fpgadrive_bak.c 2 1
  [2]: fpgadrive_pdt.c 3 1
  [3]: gadrive_fpgpdt.c 4 1
  [4]: fpga.c 1 2
  [5]: 3456789ABCDEFG.c 6 1
  [6]: fpgadrive2.c 7 1
  [7]: fpgadrive_bak2.c 8 1
posted @ 2016-12-02 09:44  clover_toeic  阅读(663)  评论(0编辑  收藏