题目说明:
简单错误记录
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 64M,其他语言128M
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
文件路径为windows格式
如:E:V1R2productfpgadrive.c 1325
输出描述:
将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1
结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
如果超过8条记录,则只输出前8条记录.
如果文件名的长度超过16个字符,则只输出后16个字符
输入例子1:
E:V1R2productfpgadrive.c 1325
输出例子1:
fpgadrive.c 1325 1
C语言实现代码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 struct record { 6 char filename[256]; 7 int line; 8 int count; 9 struct record *prev; 10 struct record *next; 11 }; 12 13 static struct record *header = NULL; 14 15 static char *getfilename(char *str) 16 { 17 char s[2] = "\"; 18 char *token, *pretoken; 19 20 if (str == NULL) { 21 return NULL; 22 } 23 24 pretoken = NULL; 25 token = strtok(str, s); 26 while (token != NULL) { 27 pretoken = token; 28 token = strtok(NULL, s); 29 } 30 31 return pretoken; 32 } 33 34 void fillRecord(char *filename, int line) 35 { 36 struct record *curNode, *pTmp; 37 38 if (filename == NULL || line == -1) { 39 return; 40 } 41 42 /* 从已有节点查找,找到就++count,没找到就重新申请节点插入链表 */ 43 for (curNode = header->next; curNode != header; curNode = curNode->next) { 44 if (strcmp(curNode->filename, filename) == 0 && curNode->line == line) { 45 ++(curNode->count); 46 return; 47 } 48 } 49 50 pTmp = (struct record*)malloc(sizeof(struct record)); 51 if (pTmp == NULL) { 52 return; 53 } 54 else { 55 memset(pTmp->filename, 0, sizeof(pTmp->filename)); 56 memcpy(pTmp->filename, filename, sizeof(pTmp->filename) - 1); 57 pTmp->line = line; 58 pTmp->count = 1; 59 } 60 /* 将节点插入双向链表尾部 */ 61 pTmp->prev = header->prev; 62 header->prev->next = pTmp; 63 header->prev = pTmp; 64 pTmp->next = header; 65 } 66 67 void insertsort(struct record *header) 68 { 69 struct record *P_node, *j_node, *pTmp; 70 char tmpfile[17] = {0}; 71 int tmpline; 72 73 if (header->next == header) { 74 return; 75 } 76 77 pTmp = (struct record*)malloc(sizeof(struct record)); 78 if (pTmp == NULL) { 79 return; 80 } 81 82 for (P_node = header->next->next; P_node != header; P_node = P_node->next) { 83 memcpy(pTmp->filename, P_node->filename, sizeof(P_node->filename)); 84 pTmp->count = P_node->count; 85 pTmp->line = P_node->line; 86 j_node = P_node; 87 for (j_node = P_node; j_node->prev != header && j_node->prev->count < pTmp->count; j_node = j_node->prev) { 88 /* 将j_node的prev节点往后移 */ 89 memcpy(j_node->filename, j_node->prev->filename, sizeof(j_node->prev->filename)); 90 j_node->line = j_node->prev->line; 91 j_node->count = j_node->prev->count; 92 } 93 memcpy(j_node->filename, pTmp->filename, sizeof(pTmp->filename)); 94 j_node->line = pTmp->line; 95 j_node->count = pTmp->count; 96 } 97 98 free(pTmp); 99 } 100 101 int main(int argc, char **argv) 102 { 103 char buf[4096]; 104 char *strpath, *filename; 105 int line; 106 char *strto; 107 char s[2] = " "; 108 struct record *pNode; 109 int i, len; 110 111 /* 申请一个struct record节点作为header,count赋值为-1 */ 112 header = (struct record*)malloc(sizeof(struct record)); 113 if (header == NULL) { 114 return -1; 115 } 116 else { 117 header->count = -1; 118 header->prev = header; 119 header->next = header; 120 } 121 122 while (fgets(buf, sizeof(buf), stdin)) { 123 strto = strtok(buf, s); 124 strpath = strto; 125 strto = strtok(NULL, s); 126 127 line = atoi(strto); 128 /* 从strpath中提取出文件名 */ 129 filename = getfilename(strpath); 130 /* 更新节点或者申请一个新节点 */ 131 fillRecord(filename, line); 132 } 133 134 /* 稳定的插入排序算法 */ 135 insertsort(header); 136 137 i = 0; 138 pNode = header->next; 139 while (pNode != header && i < 8) { 140 len = strlen(pNode->filename); 141 if (len > 16) { 142 memmove(pNode->filename, pNode->filename + (len - 16), 16); 143 pNode->filename[16] = '