2013-10-04 66 views
0

我正在創建一個簡單函數printNode,它接受一個int或字符串「all」,並打印相應的輸出。該函數的INT方面效果很好,但是當我打電話使用stringstream.fail()檢查輸入是int還是字符串

printNode all 

功能打印「錯誤:無效的參數」,我似乎無法找出原因。

int main() { 
    ... 
    getline(cin, line) 
    stringstream lineStream(line); 
    stringstream elineStream(line); 
    printNode(lineStream, elineStream); 
    ... 
} 


int printNode(stringstream& lineStream, stringstream& elineStream) { 
//String aspect of printNode 
int nodeid; 
string name; 

// Parsing nodeid or name 
lineStream >> nodeid; 

// If parsing to nodeid fails, check if input is string "all" 
if (lineStream.fail()) { 
    elineStream >> name; 
    if (elineStream.fail()) { 
     if (elineStream.eof()) { 
      cout << "Error: too few arguments" << endl; 
      return 0; 
     } 
     else { 
      cout << "Error: invalid argument" << endl; 
      return 0; 
     } 
    } 
    if (name != "all") { 
     cout << "Error: invalid argument" << endl; 
     return 0; 
    } 
    // Check for too many arguments 
    elineStream >> ws; 
    if (!elineStream.eof()) { 
     cout << "Error: too many arguments" << endl; 
     return 0; 
    } 

    // Print output for input "all" 
    cout << "Print: all nodes" << endl; 
    return 1; 
} 

任何幫助將不勝感激。

+0

再多做一點工作,您就可以將其作爲一個獨立的,可編輯的示例。另外,請注意,你應該返回0成功,1返回失敗 - 你是這樣做倒退。 –

+0

@JohnZwinck關於成功/失敗的'1' /'0',爲什麼不只是返回一個'bool'? –

+0

@JoachimPileborg:你說得很對!我把它混合起來,並從main()中讀取這些返回值。他們會比布爾(或例外)更好。 –

回答

0

您要給它printNode all作爲輸入,而它只需要all。我試過你的代碼,它的工作正常(當然,給它printNode all失敗,無效的參數)。

作爲一個方面說明,您可以通過清除第一個字符串上的錯誤標誌避免使用兩個流。也就是說,如果在看到數字讀取失敗後添加lineStream.clear();,則所有​​可能只是lineStream


從你的文字,我看到一些奇怪的事情,我也想澄清(以防萬一):

but when I call

printNode all 

通過在命令行寫,你是不是調用函數。當你寫這個函數時會調用:

printNode(lineStream, elineStream); 

在你的源代碼中。如果在命令行中編寫printNode all,那麼所有該字符串(因爲您讀完整行)將被傳輸到流中,而不僅僅是all

0

有一個更簡單的方式來獲得的「命令」,其所有的選項,通過使用std::copystd::istream_iteratorstd::back_inserter所有的話複製到std::vector。然後,它只是簡單檢查矢量的大小,看看該命令是否合法。

東西線這樣的:

std::vector<std::string> command_and_args; 

std::copy(std::istream_iterator<std::string>(lineStream), 
      std::istream_iterator<std::string>(), 
      std::back_inserter(command_and_args)); 

if (command_and_args.size() == 0) 
    std::cout << "Error: No command or arguments\n"; 
else if (command_and_args.size() == 1) 
    std::cout << "Error: To few arguments\n"; 
else if (command_and_args.size() > 2) 
    std::cout << "Error: To many arguments\n"; 
else 
{ 
    // Got the command and one argument 
    // Command in `command_and_args[0]` 
    // Argument in `command_and_args[1]` 
} 

std::copy部分可用於所有命令,而檢查必須是單獨的。


編輯:其實,參數的數目的檢查可以是自動的也一樣,如果你創建詳細的命令結構(命令字符串,布爾說,如果是必需的參數,一個參數的最小數,最大參數的數量,以及命令處理程序的一個對象std::function)。使用這個結構創建一個表,並通過它來查找命令,檢查參數計數(如果需要),然後調用函數對象。然後函數對象可以檢查單個參數。

相關問題