1

wpa_cli を介して SCAN および SCAN_RESULTS コマンドを実行し、wifi スキャン結果を取得する C コードに取り組んでいます。特定のシナリオで、SCAN_RESULTS 出力を解析してキー管理と 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」の間に 2 つの連続したタブ (\t\t) が存在することがわかりました。sscanf コードを変更して機能させる方法についての指針

4

1 に答える 1

1

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]);
}

2 番目の選択肢、使用しますstrtok()\tOPが望むかもしれないが、それがリード/連続を処理するかどうかはわかりません。

以下は、OPのニーズを満たしていない私の元の回答です。


** 元の回答 **

まず、any の結果は次のsscanf()ように評価する必要があります。

if (3 != sscanf(buf, "%s\t%s\t%[^\n]s", a, b, c)) handle_error();

OPが示唆するように、フィールドが本当に\t分離されている場合は、使用します

if (3 != sscanf(buf, "%[^\t]%*1[\t]%[^\t]%*1[\t]%[^\n]", a, d, c)) handle_error();

"%[^\t]"タブが見つかるまでスキャンします。
"%*1[\t]" 1 つのタブをスキャンします。sscanf() の結果を保存したり追加したりしません。
"%[^\n]"行末が見つかるまでスキャンします。

注:
簡単にするために、OP の 5 つのパラメーターではなく 3 つを使用しています。
ではsscanf()" \t "と同じことを行い" "ます。
では"%[^\n]s、確かにs必要ありません。

于 2013-10-15T21:10:20.757 に答える