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


    【题目】

    开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
    处理:
    1、 记录最多8条错误记录,循环记录,对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加;
    2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
    3、 输入的文件可能带路径,记录文件名称不能带路径。
    Input:
    一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
    如:E:V1R2productfpgadrive.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:
    ");
        unsigned int dwRecIdx = 0;
        for(; dwRecIdx < ERR_NUM && '' != gErrorMap[dwRecIdx][0]; dwRecIdx++) {
            printf("  [%u]: %s
    ", dwRecIdx, gErrorMap[dwRecIdx]);
        }
    }
    int CreateErrorRecord(char *pszErrorInfo){
        if(NULL == pszErrorInfo || '' == *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 && '' != 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
    
  • 相关阅读:
    http uri唯一标识
    http协议
    python模块 sys
    file 文件的操作
    库的介绍及使用
    python os模块
    python的序列化与反序列化
    python 字典的定义以及方法
    python字符串的常用方法
    在Windows下使用adb logcat grep
  • 原文地址:https://www.cnblogs.com/clover-toeic/p/6067499.html
Copyright © 2020-2023  润新知