我正在为一个大学项目写一个基于文本的拼字游戏实现。
规范规定用户的位置输入必须从单行读取,如下所示:
Coordinates of the word's first letter and orientation (<A – P> <1 – 15> <H ou V>): G 5 H G 5 H是该特定示例的用户输入。如图所示,订单必须是char int char。
阅读用户输入的最佳方式是什么?
如果用户搞砸了,cin >> row >> column >> orientation会导致崩溃。
getline和随后的string解析器是一个有效的解决方案,但需要做一些工作。
有没有另一种更好的方法来做这件事,而我却错过了?
耽误您时间,实在对不起!
发布于 2010-05-14 23:23:01
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的输入失败,则在原始输入流中设置失败位)。
发布于 2010-05-14 22:59:01
很抱歉,getline和解析字符串是你最好的选择。但是,您可以通过创建一个类来表示输入选项,然后重载operator>>,以便它使用getline并解析字符串,从而使您的系统更具可重用性。这样,您就不必重复任何解析代码。
发布于 2010-05-15 02:00:05
我得到了类似这样的东西:
#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将被成功复制到row char变量中。但是,由于B不是数值型的,它会忽略剩余的缓冲区,因此B和C会丢失。您会收到一条错误消息,提示您为列输入了无效的值,但是一旦成功输入了有效的数字,您仍然需要再次输入方向。因此,基于这个应用程序,用户并不清楚这一点。您可以很容易地进行这样的修改,这样,如果您输入了无效的输入,它将要求您重新输入整个内容。
https://stackoverflow.com/questions/2835092
复制相似问题