2017-07-14 838 views
3

對於命令行應用程序,我需要將輸入字符串與命令模式進行比較。白色空間需要被忽略。比較使用sscanf的字符串,但忽略空格

此行應匹配輸入字符串如「刪除所有」和「刪除所有」:

int rc = sscanf(input, "drop all"); 

但到底是什麼在這裏表示成功的比賽?

+2

你似乎選擇了一個錯誤的工具... –

+0

@EugeneSh。也許,但是一些命令也會把數字等作爲參數。所以這是一個沒有參數的特例。 – mwarning

回答

5

使用"%n"記錄掃描停止的位置。

將格式中的空格添加到需要忽略的WS input中的任何位置。

int n = -1; 
sscanf(input, " drop all %n", &n); 
// v---- Did scanning reach the end of the format? 
// |   v---- Was there additional text in `input`? 
if (n >= 0 && input[n] == '\0') Success(); 
+2

老實說,我不明白這個代碼在沒有問題中給出的要求的情況下做了什麼。 –

+0

這將工作與'放下所有'和'放下所有'? (評論解析器似乎被打破......) – VTT

+0

@VTT:你爲什麼不嘗試它?它不難打字,而且複製'n'paste使它更容易。例如,格式字符串中的空格匹配0個或多個空格字符 - 空格,製表符,換行符。而Markdown則很難通過反標和空格(或其他反標)得到您想要的結果。 –

1

與其使用髒數據工作,通常最好清理它然後使用它。清理必須只發生一次,而髒數據會在每次使用時增加代碼的複雜性。這一步通常被稱爲「正常化」。在使用前將輸入標準化爲規範形式。

通過修剪空白來清理輸入,並執行任何其他規範化操作(例如摺疊和規範化內部空白)。

您可以編寫自己的修剪功能,但我建議您使用預先存在的功能,如Gnome Lib's g_strstrip()。 Gnome Lib帶來了各種方便的功能。

#include <glib.h> 

void normalize_cmd(char *str) { 
    g_strstrip(str); 

    // Any other normalization you might want to do, like 
    // folding multiple spaces or changing a hard tab to 
    // a space. 
} 

然後,您可以在標準化輸入上使用strcmp

// This isn't strictly necessary, but it's nice to keep a copy 
// of the original around for error messages and such. 
char *cmd = g_strdup(input); 

normalize_cmd(cmd); 

if (strcmp(cmd, "drop all") == 0) { 
    puts("yes"); 
} 
else { 
    puts("no"); 
} 

把所有規範化放在前面減少了所有下游代碼必須使用該輸入的複雜性;他們不必不斷重複對髒數據的相同擔憂。通過將所有規範化放在一個地方,而不是遍佈整個代碼,你可以確定它是一致的,並且規範化方法可以一致地更新。

+0

'strcmp(「drop \ tall」,「drop all」)'不匹配。通常,這種「清理」包括將多個_空白space_轉換爲單個''''的合格。 – chux

+0

@chux當然。在處理數據之前,請執行任何額外的清理和規範化操作。 – Schwern

+0

它是一把雙刃劍。按照建議進行清理對​​後續處理非常有用,但原始輸入對於日誌記錄和調試很有用。與任何用戶輸入一樣,這是邪惡的,在審覈之前不應使用。 – chux