0

我为我的计算机科学课编写了一个程序,该程序可以验证和解决 .txt 文件中的数独难题,但我想更进一步,编写一个程序,使输入和数独游戏变得容易。我相信您可以根据此代码找出文件的格式。我唯一的问题是最后一个 cin 被跳过了,这个选项对我很重要。任何见解将不胜感激!

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct s {
s();
~s() {/*zzzz*/}
void show_grid();
void set (int &r, int &c, int &v) {g[r][c] = v;}
private:
int g[9][9];
};

//************************************************************************

void s::show_grid() {

//print game out to check it
cout << "  |  -------------------------------  |" << endl;
for (int k=0; k<81; k++) {
    if (k%3 == 0)
        cout << "  |";
    cout << "  " << g[k/9][k%9];
    if (k%9 == 8) {
        cout << "  |" << endl;
        if ((k/9)%3 == 2)
            cout << "  |  -------------------------------  |" << endl;
    }
}
cout << endl;
}

//************************************************************************

s::s() {

//initialize all elements to zero
for (int i=0; i<9; i++) {
    for (int j=0; j<9; j++) {
        g[i][j] = 0;
    }
}
}

//************************************************************************

void create_name (string &name) {

//append .txt extension LIKE IT OR NOT
string ext = name;
ext.erase(ext.begin(), ext.end() - 4);

if (ext.compare(".txt")!=0)
    name.append(".txt");
}

//************************************************************************

int main () {

s g;
string name;
string yon("");
int count = 0;
int row, col, val, rcv;
ofstream os;

cout << "Enter game file name: ";
cin >> name;

create_name(name);

//open and do typical checks
os.open(name.c_str());
if (os.fail()) {
    cerr << "Could not create " << name << ". Waaaah waaaaaaaaaah...\n\n";
    return 0;
}

//useful output (hopefully)
cout << "Enter grid coordinates and value as a 3-digit number,\n"
    << "from left to right, row by row.\n" 
    << "(e.g. 2 in first box would be 112)\n";

//take input as one int, to be user friendly
while (cin >> rcv && count < 81) {
    row = (rcv / 100) - 1;
    col = ((rcv / 10) % 10) - 1;
    val = rcv % 10;
    os << row << " " << col << " " << val << endl;
    g.set (row, col, val);
    count++;
}

os.close();

//From here down is broken, but it still compiles, runs, and works
cout << "Show grid input(y/n)?\n";
cin >> yon;

if (yon.compare("y")==0)
    g.show_grid();
else if (yon.compare("n")==0)
    cout << "Peace!\n";

return 0;
}
4

3 回答 3

1

问题在这里:

while (cin >> rcv && count < 81)

考虑在以下情况下会发生什么count==81:首先,rcv将从 输入cin,然后才将条件count < 81评估为假。循环将停止,并且 的值rcv将被忽略。因此,您有效地阅读了一个输入太多。

您应该更改评估顺序,以便count首先检查:

while (count < 81 && cin >> rcv)

编辑

根据您上面的评论,您实际上期望读取的值少于 81 个。在这种情况下,我建议让用户输入一个特殊值(例如 0)来终止循环。你只需要添加if (rcv==0) break;. 如果你只是输入了一个无效的值,那么cin流将被置于失败状态,进一步的输入将不会成功。

于 2012-11-01T16:49:01.927 回答
0
cin >> yon

实际上仍然读入一个变量,它只是读入while循环发现为假的变量。当 while 循环条件返回 false 时,rcv 被忽略,因此该数字保留在输入流中等待下一个 cin 语句。当调用 yon 时,用于 rcv 的数字被读入 yon,给你一些奇怪的错误。

最好使用interjay的方法:

while (count < 81 && cin >> rcv)
于 2012-11-01T17:24:55.047 回答
0

尝试类似:

//useful output (hopefully)
cout << "Enter grid coordinates and value as a 3-digit number,\n"
    << "from left to right, row by row.\n" 
    << "(e.g. 2 in first box would be 112)\n"
    << "or Z to end the loop\n";  // 1

//take input as one int, to be user friendly
while (count < 81 && cin >> rcv ) { // 2
    row = (rcv / 100) - 1;
    col = ((rcv / 10) % 10) - 1;
    val = rcv % 10;
    os << row << " " << col << " " << val << endl;
    g.set (row, col, val);
    count++;
}

if(!std::cin) {  // 3
  std::cin.clear();
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}

1)让用户知道他可以输入无效字符。不一定是Z,实际上任何非数字字符都可以。

2) 按&&.

3) 如果std::cin处于错误状态,清除错误并忽略Z.

于 2012-11-01T18:30:44.617 回答