解析wpa_cli扫描结果输出的代码
我正在编写一个C代码,它通过wpa_cli执行扫描和扫描结果命令,并获取wifi扫描结果。在某些情况下,我在解析扫描结果输出以捕获密钥管理和SSID字段时遇到问题 我用来读取所有参数的代码是解析wpa_cli扫描结果输出的代码,c,wifi,C,Wifi,我正在编写一个C代码,它通过wpa_cli执行扫描和扫描结果命令,并获取wifi扫描结果。在某些情况下,我在解析扫描结果输出以捕获密钥管理和SSID字段时遇到问题 我用来读取所有参数的代码是 sscanf(buf, "%s \t %s \t %s \t %s \t %[^\n]s", bssid, freq, siglevel, keymgmt, ssid); wpa_cli SCAN_RESULTS命令的输出将是 bssid / frequency / signal level / flag
sscanf(buf, "%s \t %s \t %s \t %s \t %[^\n]s", bssid, freq, siglevel, keymgmt, ssid);
wpa_cli SCAN_RESULTS命令的输出将是
bssid / frequency / signal level / flags / ssid
00:00:00:00:00:00 2462 -49 [WPA2-PSK-CCMP][ESS] MYSSID
11:11:11:11:11:11 2437 -64 [WPA2-PSK-CCMP][ESS] ANOTHERSSID
其中字段由制表符(\t)分隔,通过上面的输出,我的代码可以正常工作。但当我的扫描结果有一些开放的网络,然后我的代码中断,我不知道如何改变代码,以满足我的要求
wpa_cli SCAN_RESULTS命令与开放网络的输出
bssid / frequency / signal level / flags / ssid
00:00:00:00:00:00 2462 -49 [WPA2-PSK-CCMP][ESS] MYSSID
22:22:22:22:22:22 2437 -72 OPENSSID
在上面的输出中,我的代码报告持有“OPENSSID”的keymgmt变量,并且ssid变量为空。但是我希望keymgmt变量为空,ssid保存“OPENSSID”。当我尝试将上述输出捕获到文件并尝试hexdump时,我可以看到“信号电平”和“ssid”之间有两个连续的选项卡(\t\t)。任何关于如何更改sscanf代码以使其工作的指针sscanf()
格式无法按预期工作
IMHO没有一种格式的sscanf()
可以用“
(或跳过它)填充目标字符串,然后用文本填充后续目标字符串。一旦scanf()
在目标字符串中找不到任何内容,扫描就会停止
给出了替代代码
int ScanTabbedData(const char *s, char *data[], size_t n) {
size_t i = 0;
const char *Start = s;
while (1) {
if ((*s == '\t') || (*s == '\0')) {
if (i >= n) {
return -1; // More than n data
}
size_t Length = s - Start;
memcpy(data[i], Start, Length);
data[i][Length] = '\0';
i++;
if (*s == '\0') {
return i;
}
s++;
Start = s;
}
else s++;
}
return 0;
}
int main() {
char *str1= "Test\tHope\tHello";
char *str2 = "Test\t\tHello";
char *t[3];
t[0] = malloc(100); t[1] = malloc(100); t[2] = malloc(100);
int n;
n = ScanTabbedData(str1, t, 3);
printf("%d:%s:%s:%s\n", n,t[0], t[1], t[2]);
n = ScanTabbedData(str2, t, 3);
printf("%d:%s:%s:%s\n", n,t[0], t[1], t[2]);
}
第二种选择,使用strtok()
。不过,我不确定它是否能按照OP的要求处理潜在客户/连续\t
下面是我的原始答案,它不符合OP的需要
**原始答案** 首先,任何
sscanf()
的结果都应按照以下步骤进行评估:
if (3 != sscanf(buf, "%s\t%s\t%[^\n]s", a, b, c)) handle_error();
如果如OP所示,字段确实是分开的,请使用
if (3 != sscanf(buf, "%[^\t]%*1[\t]%[^\t]%*1[\t]%[^\n]", a, d, c)) handle_error();
“%[^\t]”
扫描直到找到选项卡。“%*1[\t]”
扫描1选项卡,不要保存或添加到sscanf()结果。“%[^\n]”
扫描直到找到行尾
注:为了简单起见,使用了3个而不是OP的5个参数。
在
sscanf()
在“%[^\n]s
中,当然不需要s
。sscanf()
格式未按预期工作
没有一种格式的sscanf()
可以用“
(或跳过它)填充目标字符串,然后用文本填充后续目标字符串。一旦scanf()
在目标字符串中找不到任何内容,扫描就会停止
给出了替代代码
int ScanTabbedData(const char *s, char *data[], size_t n) {
size_t i = 0;
const char *Start = s;
while (1) {
if ((*s == '\t') || (*s == '\0')) {
if (i >= n) {
return -1; // More than n data
}
size_t Length = s - Start;
memcpy(data[i], Start, Length);
data[i][Length] = '\0';
i++;
if (*s == '\0') {
return i;
}
s++;
Start = s;
}
else s++;
}
return 0;
}
int main() {
char *str1= "Test\tHope\tHello";
char *str2 = "Test\t\tHello";
char *t[3];
t[0] = malloc(100); t[1] = malloc(100); t[2] = malloc(100);
int n;
n = ScanTabbedData(str1, t, 3);
printf("%d:%s:%s:%s\n", n,t[0], t[1], t[2]);
n = ScanTabbedData(str2, t, 3);
printf("%d:%s:%s:%s\n", n,t[0], t[1], t[2]);
}
第二种选择,使用strtok()
。我不确定它是否能按照OP的要求处理潜在客户/连续的\t
下面是我的原始答案,它不符合OP的需要
**原始答案** 首先,任何
sscanf()
的结果都应按照以下步骤进行评估:
if (3 != sscanf(buf, "%s\t%s\t%[^\n]s", a, b, c)) handle_error();
如果如OP所示,字段确实是分开的,请使用
if (3 != sscanf(buf, "%[^\t]%*1[\t]%[^\t]%*1[\t]%[^\n]", a, d, c)) handle_error();
“%[^\t]”
扫描直到找到选项卡。“%*1[\t]”
扫描1选项卡,不要保存或添加到sscanf()结果。“%[^\n]”
扫描直到找到行尾
注:为了简单起见,使用了3个而不是OP的5个参数。
在
sscanf()
在“%[^\n]s
中,当然不需要s
我很确定那不是正则表达式。正则表达式是一种非常特殊的文本处理工具,我很确定这不是正则表达式。正则表达式是一种非常特殊的文本处理工具。很抱歉,这对我不起作用。我刚刚尝试了以下代码charstr[]=“Test Hope Hello”;ret=sscanf(str,“%[^\t]%*1[\t]%[^\t]%*1[\t]%[^\n]”,t1,t2,t3)代码>这里字符串str由tab分隔,当我尝试打印值时,我可以看到ret=1 t1=Test,t2和t3都是empty@BabaC你的意思是说你使用了“Test\tHope\tHello”还是在“\uu”是制表符的地方编写了“Test\u Hope\u Hello”?@BabaC你的评论说你尝试了“”%[^\t]%*1[\t]%[^\t]…”
。您是否尝试过使用发布的格式“%[^\t]%*1[\t]%[…”
?哎呀,我从来没有想过一个简单的空格可以改变行为(我添加了空格以便于阅读),正如前面所指出的,代码使用了“Test\tHope\tHello”,但这段代码仍然可以很好地解析3个参数,但我最初的问题不同。我需要的是char str1[]“Test Hope Hello”char str2[]=“Test Hello”sscanf(str1,”,t1,t2,t3);;sscanf(str2,”,t1,t2,t3);
在第一次打印中我应该得到t1=Test,t2=Hope,t3=Hello,在下一次打印中t1=Test,t2=,t3=HelloI我忘了添加制表符分隔,这就是str1[]=“Test\tHope\tHello”和str2[]。”Test\t\tHello“
。请注意,在str2中有两个组成选项卡(\t\t)。很抱歉,这对我不起作用。我刚刚尝试了以下代码char str[]=“Test Hope Hello”;ret=sscanf(str,“%[^\t]]*1[\t]%[^\t]%*1[\t][^\n]”,t1,t2,t3)这里字符串str由tab分隔,当我试图打印我可以看到的值ret=1 t1=Test,t2和t3都是empty@BabaC你的意思是说你使用了“Test\tHope\tHello”还是在“\uu”是制表符的地方编写了“Test\u Hope\u Hello”?@BabaC你的评论说你尝试了“”%[^\t]%*1[\t][^\t]。。。“
。您是否尝试过使用发布的格式”“%[^\t]%*1[\t]%[…”
?哎呀,我从来没有想过一个简单的空格可以改变行为(我添加空格是为了使其易于阅读),正如前面所指出的,代码使用了“Test\tHope\tHello”,但这段代码仍然可以很好地解析3个参数,但我的初始问题不同。我需要的是char str1[]=“Test Hope Hello”;char str2[]=“Test Hello”;sscanf(str1,”,t1,t2,t3);sscanf(str2,”,t1,t2,t3);
在第一个pri中