2010-05-14 54 views
0

我正在爲大學項目編寫一個基於文本的拼字遊戲實現。C++初學者 - 從命令行讀取3個連續值的最佳方法?

說明書指出該用戶的位置輸入必須從單線讀出,這樣的:

Coordinates of the word's first letter and orientation (<A – P> <1 – 15> <H ou V>): G 5 H 

G 5 H是用戶的用於該特定示例性輸入。如圖所示,訂單必須是charintchar

什麼是閱讀用戶輸入的最佳方式?

cin >> row >> column >> orientation如果用戶擰緊,將導致崩潰。

A getline和後續的string解析器是一個有效的解決方案,但代表了一些工作。

有沒有另一種更好的方式來做到這一點,我失蹤了?

謝謝你的時間!

回答

2

getline解析不一定要添加太多的工作。既然您已經知道如何從流中讀取(更正)數據,只需讀取一行getline,然後從行中創建一個istringstream並從那裏讀取。

我要補充的一件事是,創建一個類來保存特定移動的數據非常有意義,並且該類會重載operator>>以讀取移動的數據。一個粗略的草圖會是這樣的:

class move { 
    char row; 
    int column; 
    char orientation; 
public: 
    friend std::istream &operator>>(std::istream &is, move &m); 
}; 

std::istream &operator>>(std::istream &is, move &m) { 
    std::string temp; 
    std::getline(is, temp); 
    std::istringstream buffer(temp); 

    // Now we can parse data from buffer just like we could from another stream. 
    return is; 
} 

至少現在,我沒有包括任何錯誤處理代碼。根據你想要的挑剔程度,這可能會有點棘手(例如,如果輸入來自stringstream失敗,則在原始輸入流中設置失敗位)。

+0

+1這將允許你保存移動和'撤消'它們。 – 2010-05-14 16:00:48

2

對不起,但getline和解析字符串是你最好的選擇。但是,通過創建一個類來表示輸入選項,然後重載運算符>>,以便使用getline並分析字符串,可以使系統更加可重用。這樣,您不必重複任何解析代碼。

+0

我看到:(我會等待一些更多的輸入,然後我會去做它 – 2010-05-14 15:02:08

0

另一個建議是從控制檯輸入,使用一個項目的時間和適用的錯誤檢查:

char row; 
bool is_valid = false; 
while (!is_valid) 
{ 
    while (!(cin >> row)) 
    { 
     cout << "Error reading row, please enter data again.\n"; 
    } 

    row = toupper(row); 
    static const std::string valid_rows("ABCDEFGHIJKLMNO"); 
    is_valid = valid_rows.find(row) != std::string::npos; 
    if (!is_valid) 
    { 
     cout << 'Row ' << row << ' is not a valid row letter, please re-enter.\n"; 
    } 
} 

通過閱讀一個可變的時間,而不是所有三個一次,你可以給用戶提前警告錯誤檢測。

1

我得到了這樣的事情:

#include <iostream> 
#include <limits> 
#include <string> 

using namespace std; 

template<class T> T getValue(const string& name) 
{ 
     T ret; 
     while(!(cin >> ret)) 
     { 
       // normally here you'd go into an infinite loop, but since you're going to ignore the rest of the line, you can ensure that you won't go into an infinite loop and you can re-ask the user to input the correct data 
       cout << "Invalid input for " << name << " please try again" << endl; 
       cin.clear(); 
       cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
     } 
     return ret; 
} 

int main(void) 
{ 
     bool valid = false; 
     char row, orientation; 
     int column; 

     do { 
       cout << "Enter row, column, and orientation (<A-P> <1-15> <H to V>): " << endl; 
       row = getValue<char>("row"); 
       column = getValue<int>("column"); 
       orientation = getValue<char>("orientation"); 

       if(row<'A' || row>'P') 
         cout << "Invalid row please enter A-P" << endl; 
       else if(column<1 || column>15) 
         cout << "Invalid column please enter 1-15" << endl; 
       else if(orientation<'H' || orientation>'V') 
         cout << "Invalid orientation please enter H-V" << endl; 
       else 
         valid = true; 
     } while(!valid); 

     cout << "Row: " << row << endl 
      << "Column: " << column << endl 
      << "Orientation: " << orientation << endl; 

     return 0; 
} 

當然,如果你輸入一些無效的,如:

A B C

它會產生一些潛在的混亂問題。第一個A將被成功複製到行char變量中。然而,由於B不是數字,它會忽略剩餘的緩衝區,所以你失去了B和C.您收到一條錯誤消息,指出您輸入了一個無效的列輸入,但一旦您成功輸入了有效的號碼,您仍需要再次輸入方向。所以基於這個應用程序,用戶並不清楚這一點。你可以很容易地做出這樣的修改,如果你輸入了一個無效的輸入,它會讓你輸入整個事情。