开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
文件路径为windows格式
如:E:\V1R2\product\fpgadrive.c 1325
输出描述:
将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1
结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。
如果超过8条记录,则只输出前8条记录.
如果文件名的长度超过16个字符,则只输出后16个字符
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <tuple>
using namespace std;
bool compare(tuple<string, int> a, tuple<string, int> b){
return get<1>(a) > get<1>(b);
}
int main() {
string str;
vector<tuple<string, int> > v;
while (getline(cin, str)){
int nameBeg = 0;
auto rit = find(str.rbegin(), str.rend(), '\\');
string::iterator it((++rit).base());
nameBeg = it - begin(str) + 1;
string name_line = string(begin(str) + nameBeg, end(str));
int i = 0;
for (; i != v.size(); ++i) {
if (name_line == get<0>(v[i])) {
++get<1>(v[i]);
break;
}
}
if (i == v.size())
v.emplace_back(make_tuple(name_line, 1));
}
int len = min(8, static_cast<int>(v.size()));
for (int i = 0; i < len; ++i) {
stable_sort(v.begin(), v.end(), compare);
int id = get<0>(v[i]).find(' ');
if (id > 16)
get<0>(v[i]) = string(begin(get<0>(v[i])) + id - 16, end(get<0>(v[i])));
cout << get<0>(v[i]) << " " << get<1>(v[i]) << endl;
}
return 0;
}
第一次写的结果 60%通过, 有错
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string str;
vector<string> name_lines;
vector<int> numErrs;
while (getline(cin, str)){
int nameBeg = 0;
int nameEnd = 0;
for (int i = 0; i != str.size(); ++i) {
if (str[i] == '\\')
nameBeg = i + 1;
else if (str[i] == ' ') {
break;
}
}
string name_line = string(begin(str) + nameBeg, end(str));
auto it = find(begin(name_lines), end(name_lines), name_line);
if (it == end(name_lines)) {
name_lines.emplace_back(name_line);
numErrs.emplace_back(1);
} else {
++numErrs[it - begin(name_lines)];
}
}
int len = min(8, static_cast<int>(name_lines.size()));
for (int i = 0; i < len; ++i) {
for (int j = numErrs.size() - 1; j - 1 >= i; --j) {
if (numErrs[j] > numErrs[j - 1]) {
swap(numErrs[j], numErrs[j - 1]);
swap(name_lines[j], name_lines[j - 1]);
}
}
// 错误在这里,当 k > 16 时 name_lines[i]被修改, 然后
// 没有break, 导致 k != name_lines[i].size() 成立,
// 溢出, 如果k < name_lines[i].size() 的话也就是多循环
// 一次但不会报错。
for (int k = 0; k != name_lines[i].size(); ++k) {
if (name_lines[i][k] == ' ') {
if (k <= 16) break;
name_lines[i] = string(begin(name_lines[i]) + k - 16, end(name_lines[i]));
}
}
cout << name_lines[i] << " " << numErrs[i] << endl;
}
}