1

基本的に、9x9 グリッド (数独パズル) を含むファイルがあります。現在、この数独パズルは部分的にしか完成していません。空のスペースは "_" (アンダースコア) に置き換えられています。ファイルの外観は次のとおりです。

5 _ _ _ _ _ 1 7 _ 
1 _ 6 5 _ 9 _ 4 _ 
4 7 2 1 _ 6 _ _ _ 
9 _ _ _ _ _ 5 _ _ 
_ 1 8 _ 9 5 4 _ _ 
6 _ _ 4 _ 2 3 8 9 
_ 4 _ _ _ _ 9 3 _ 
_ 9 _ 7 _ 3 _ 5 _ 
2 6 3 9 5 8 7 1 4 

そして、ここに私のコードがあります:

for(int row=0;row<9;row++)
{
    for(int column=0;column<9;column++)
    {
        fin >> num;
        if(num == '\95')
            sudokuPuzzle[row][column] = 0;
        else
            sudokuPuzzle[row][column] = num;
        cout << sudokuPuzzle[row][column] << " ";
    }
    cout << endl;
}

私が抱えている問題は、次の行にあります。

if(num == '\95')

アンダースコアの 10 進値を ASCII テーブルで調べたところ、それが見つかりました。ただし、ループ内の cout ステートメントが実行されるたびに、配列がファイルの最初の数値 5 だけで埋められていることが示されます。整数と文字を適切に比較するにはどうすればよいでしょうか?

参考までに: 基本的に私がやろうとしているのは、すべてのアンダースコアを 0 に置き換えることです。

4

5 に答える 5

3

文字から 48 を引くと、それに相当する数値が得られます。たとえば、
char num = '0';があるとします。この char '0' を数値 0 に変換するには、
int num1= num - 48;を使用できます。
タイプ「char」の変数「num」を定義して、次の
sudokuPuzzle[row][column] = num - 48;を使用するだけです。

char num;

for(int row=0;row<9;row++)
{
   for(int column=0;column<9;
   {
     fin >> num;
     if(num == '_')
        sudokuPuzzle[row][column] = 0;
     else
        sudokuPuzzle[row][column] = num - 48;
     cout << sudokuPuzzle[row][column] << " ";
}
cout << endl;
}
于 2013-11-15T06:17:46.817 に答える
3

使用する

if (num=='_')

それは本当に簡単です。

しかし、問題はコードの別の部分にあると思います-読むとき

fin >> num;

アンダースコアから int への満足のいく変換は得られません。中間の文字列変数に読み込む必要があります。

fin >> myStringVariable;

次に、その文字が数字かアンダースコアかを確認し、それに基づいて行動します。

完全なプログラムを編集:

#include <iostream>
#include <fstream>

int main(void)
{
  std::ifstream fin ("sudoku.txt");
  std::string line;
  int pos;
  int sudokuPuzzle[9][9];
  for(int row=0;row<9;row++)
  {
    getline(fin, line);
    std::cout << "as read in:         " << line << std::endl;
    while((pos = line.find("_", 0))!=std::string::npos)
    {
      line[pos] = '0';
    }
    // show that it worked:
    std::cout << "after substitution: " << line << std::endl;

    // make a copy of line to process with strtok:
    char *dup = strdup(line.c_str());

    // and now numerically:
    sudokuPuzzle[row][0] = atoi(strtok(dup, " "));
    std::cout << "after conversion:   " << sudokuPuzzle[row][0] << " ";

    for(int column=1;column<9;column++)
    {
      sudokuPuzzle[row][column] = atoi(strtok(NULL, " "));
      std::cout << sudokuPuzzle[row][column] << " ";
    }
    std::cout << std::endl;
    std::cout << std::endl;
    free(dup);
  }
}

次の出力が生成されます。これは自明だと思います。

as read in:         5 _ _ _ _ _ 1 7 _ 
after substitution: 5 0 0 0 0 0 1 7 0 
after conversion:   5 0 0 0 0 0 1 7 0 

as read in:         1 _ 6 5 _ 9 _ 4 _ 
after substitution: 1 0 6 5 0 9 0 4 0 
after conversion:   1 0 6 5 0 9 0 4 0 

as read in:         4 7 2 1 _ 6 _ _ _ 
after substitution: 4 7 2 1 0 6 0 0 0 
after conversion:   4 7 2 1 0 6 0 0 0 

as read in:         9 _ _ _ _ _ 5 _ _ 
after substitution: 9 0 0 0 0 0 5 0 0 
after conversion:   9 0 0 0 0 0 5 0 0 

as read in:         _ 1 8 _ 9 5 4 _ _ 
after substitution: 0 1 8 0 9 5 4 0 0 
after conversion:   0 1 8 0 9 5 4 0 0 

as read in:         6 _ _ 4 _ 2 3 8 9 
after substitution: 6 0 0 4 0 2 3 8 9 
after conversion:   6 0 0 4 0 2 3 8 9 

as read in:         _ 4 _ _ _ _ 9 3 _ 
after substitution: 0 4 0 0 0 0 9 3 0 
after conversion:   0 4 0 0 0 0 9 3 0 

as read in:         _ 9 _ 7 _ 3 _ 5 _ 
after substitution: 0 9 0 7 0 3 0 5 0 
after conversion:   0 9 0 7 0 3 0 5 0 

as read in:         2 6 3 9 5 8 7 1 4 
after substitution: 2 6 3 9 5 8 7 1 4 
after conversion:   2 6 3 9 5 8 7 1 4 

ボーナス

5 3 9 8 2 4 1 7 6
1 8 6 5 7 9 2 4 3
4 7 2 1 3 6 8 9 5
9 2 4 3 8 7 5 6 1
3 1 8 6 9 5 4 2 7
6 5 7 4 1 2 3 8 9
7 4 5 2 6 1 9 3 8
8 9 1 7 4 3 6 5 2
2 6 3 9 5 8 7 1 4
于 2013-11-15T05:03:34.053 に答える
0

ファイルは次のようになります。

5 _ _ _ _ _ 1 7 _ 
1 _ 6 5 _ 9 _ 4 _ 
4 7 2 1 _ 6 _ _ _ 
9 _ _ _ _ _ 5 _ _ 
_ 1 8 _ 9 5 4 _ _ 
6 _ _ 4 _ 2 3 8 9 
_ 4 _ _ _ _ 9 3 _ 
_ 9 _ 7 _ 3 _ 5 _ 
2 6 3 9 5 8 7 1 4 

つまり、ファイルの最初の行は次のように表現できます。

char line[] = { '5', '_', '_', '_', '_', '_', '1', '7', '_' };

これは char 配列ですが、末尾の nul を追加していないため、文字列ではありません。

この配列には何が含まれていますか?

最初の文字はline[0]、ASCII 文字 '5' を表します。これは整数値 と同じではありません。これは'5' の5ASCII コードです。アスキー テーブルを見ると、「5」が ASCII 文字 53 であることがわかります。

したがって、line[0] は、ASCII 文字として印刷される場合は「5」と表示されますが、整数値として印刷される場合は「53」と表示されます。

#include <iostream>

int main() {
    char fourtyTwoPlus11 = 53;
    std::cout << fourtyTwoPlus11 << "\n";
    std::cout << static_cast<int>(fourtyTwoPlus11) << "\n";
    return 0;
}

ライブデモ: http://ideone.com/JEUcLO

ファイルには、整数値ではなく ASCII 文字が既に含まれているようです。したがって、文字ごとに、実際に数値に変換する必要があります。次のようなことができます。

enum { NumColumns = 9, UnknownValue = -1 };

char line[NumColumns] = { '5', '_', '_', '_', '_', '_', '1', '7', '_' };
int values[NumColumns];

for (size_t i = 0; i < NumColumns; ++i) {
    char col = line[i];
    if (col == '_')
        values[i] = UnknownValue;
    else
        values[i] = col - '0';
}

整数値は 0 ~ 9 の範囲にあり、ASCII テーブルには 0、1、2 ... 9 の順序で数字が格納されているという知識を使用して取得します。 9' - '0' = 9.

ここでは不明な値を表すために -1 を使用することにしましたが、ここでは 0 を使用することも簡単にできます。

于 2013-11-15T05:40:44.380 に答える
0

この種の状況 (char または int の入力を取得する) では、通常、次のトリックを使用します。

char c;
int n;
cin >> c;
if(c != '_'){
    cin.putback(c);
    cin >> n;
}

fin似ている。

于 2013-11-15T05:53:30.060 に答える