解析wpa_cli扫描结果输出的代码

解析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

我正在编写一个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 / 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中