题目:IP数据包解析
待传
分析
考察三个知识点
- 16机制转10机制
- string字符出提取子串
- printf格式化输出
比较细节的一个点
使用getline时,假如前面已经有一个输入T,我们默认输入T之后敲回车,如此读入T的同时,也在输入流中多加了一个回车。
因为cin, scanf等输入都会省略这个多余的换行,但是getline不会,于是就把换行读入作为一个数据了,所以要在输入T之后,使用cin.get()把多余的换行符读出来。
代码演示
int T;
string tcp;
cin >> T;
cin.get();//读入多余的换行符
getline(cin, tcp);
16机制转10机制(默认输入一个字符串)
int S16to10(string s) {
int m = 1;
int res = 0;
for (int i = s.size() - 1; i >= 0; i--) {
int n;
if (s[i] >= 'a' && s[i] <= 'f') {
n = s[i] - 'a' + 10;
} else {
n = s[i] - '0';
}
res += n * m;
m *= 16;
}
return res;
}
完整代码
#include "iostream"
#include "cstring"
#include "string"
using namespace std;
const int N = 1000;
int T;
string tcp;
int S16to10(string s) {
int m = 1;
int res = 0;
for (int i = s.size() - 1; i >= 0; i--) {
int n;
if (s[i] >= 'a' && s[i] <= 'f') {
n = s[i] - 'a' + 10;
} else {
n = s[i] - '0';
}
res += n * m;
m *= 16;
}
return res;
}
int main() {
cin >> T;
cin.get();
for (int i = 1; i <= T; i++) {
getline(cin, tcp);
printf("Case #%d\n", i);
printf("Total length = %d bytes\n", S16to10(tcp.substr(6, 5).erase(2, 1)));
printf("Source = %d.%d.%d.%d\n", S16to10(tcp.substr(36, 2)), S16to10(tcp.substr(39, 2)), S16to10(tcp.substr(42, 2)),
S16to10(tcp.substr(45, 2)));
printf("Destination = %d.%d.%d.%d\n", S16to10(tcp.substr(48, 2)), S16to10(tcp.substr(51, 2)), S16to10(tcp.substr(54,
2)), S16to10(tcp.substr(57, 2)));
printf("Source Port = %d\n", S16to10(tcp.substr(60, 5).erase(2, 1)));
printf("Destination Port = %d\n\n", S16to10(tcp.substr(66, 5).erase(2, 1)));
}
return 0;
}
贴一个string常见操作
//在末尾添加字符
s+='a' or s.append('a');
//获取字符串长度
s.size(),s.length();
//pos为提取子串的起始下标,len子串的长度
s.substr(pos,len);
// 判空
s.empty();
//清空
s.clear();
//p为待查找的子字符串,pos为开始查找的下标,默认为0
//查找成功返回子串的下标,查找失败返回一个很大的数
s.find(p,pos);
if(s.find(p,pos)!= string::npos)
//找到第一个 与子串任意字符匹配都行的地方
s.find_first_of(p);
//找到最后一个 与子串任意字符匹配都行的地方
s.find_last_of(P);
//将string转化为int类型
int a = stoi(s);
//删除某个子串
//从pos下标开始,删除n个字符
s.erase(pos,n);