2

私の現在の C++ のバックグラウンドは、大学レベルのコースを 1 学期受講したことです。

if-else ステートメント内で割り当てた値をその外に保持する方法を理解するのに苦労しています。事前に外部で宣言し、ポインターを使用してメモリアドレス自体を処理する場合、それは公正なゲームになると考えましたが、明らかにそうではありません。

今のところ私の「MAZE」ファイル:

. # # # # # # 
. . . . . # # 
# . # # . # # 
# . # # . . # 
# . . # # . # 
# . # # . . # 
# . # # . # # 
. . . # . . . 
# # . . . # #

そして、これが私の maze.h ファイル内にあるもので、コンストラクターを定義しています。まだほとんどのプログラムに慣れていませんが、私の main.cpp は既にテキスト ファイルの迷路の寸法の計算を処理しており、それから呼び出します。

Maze *testMaze = new Maze(rows,columns);

私の maze.h ファイルには bool maze[0][0] がプライベート メンバーとしてリストされています。コードの最初の実行時にはまだ迷路のサイズを知る方法がないため、0 に設定されています。コードを実行してサイズを計算し、行と列をパラメーターとして Maze コンストラクターに渡します。

パラメーターを持つ私の maze.cpp ファイルのコンストラクター:

Maze::Maze(int rows, int columns)
{
    string mazeRow="";
    int roIndex=0; //Row Index
    int coIndex=0; //Column Index
    bool maze[rows][columns];
    bool* target = NULL;

    ifstream input;
    input.open("MAZE",ios::in);
    if(input)
    {

        while (getline(input, mazeRow))
        {
            //Testprint this row of the maze.
            cout << mazeRow << endl; //mazeRow is the data in that row of the text file.
            //Store each non-space value.


            for (coIndex=0; coIndex<mazeRow.length(); coIndex++) //For each character in that row...
            {
                char check=mazeRow[coIndex];
                target = &maze[roIndex][coIndex];   
                if (check=='.') //Path
                {
                    *target=true;
                cout << *target << " "; //These print statements print correctly.
                }
                else if (check=='#') //Wall
                {
                    *target=false;
                cout << *target << " "; //These print statements print correctly.
                }
                else if (check==' ') //Space
                {
                //ignore spaces
                }
                else //For all other cases, an invalid character is present.
                {
                    cout << "Invalid character detected." << endl;
                }
                cout << *target << " "; //For some odd reason, this line BY ITSELF doubles up print. Ex. instead of printing 1 1 0 1 0, it would print 1 1 1 1 0 0 1 1 0 0.
            }
        cout << "End of row." << endl;
        roIndex++;
        }
    }
    input.close();

    cout << "Storage completed." << endl;

    for (int i=0; i<rows; i++)
    {
    cout << "Row " << i << endl;
        for (int j=0; j<columns; j++)
        {
        /* This is the print test to see if the values 
           are retained outside of the first block. 
           None of them print the maze file properly.
        */
        if (maze[i][j] == true)
            cout << maze[i][j] << "\t" << "." << "\t";
        if (maze[i][j] == false)
            cout << maze[i][j] << "\t" << "#" << "\t";
        cout << "Column " << j << endl;
        }
        cout << "End of row." << endl;
    }
    cout << "Verification completed." << endl;
}

こちらで質問するのは初めてなので、わからないことがあれば教えてください。


ここにアップデートを載せたかっただけです。結局のところ、私は過度にストレスを感じていたか、睡眠不足か、またはその両方だった. このコードを数時間置いて、もう一度見直してみたところ、コードに非常に多くの論理エラーが見つかりました。これには、特定の変数が存在する理由やそれらが何のために使用されているかを忘れたり、すべてを明確に考えていなかったりすることが含まれますが、これらに限定されませんループ内でのインクリメント (++) の後遺症、またはそのようなずさんなミス。以下の回答/コメントのいくつかを取得し、自分のコードの理解を更新して、これらのエラーを修正するのに役立ちました. できたら、できれば完成したコードを提供します。


問題を解決しました。数時間以内に自己回答し、実際に何が起こったのかを説明できるようになります.

4

5 に答える 5

0

まず、皆さんのご協力に感謝します。私は当初、エラーは変数のローカルコピーのみを変更するステートメントに関連する問題に起因すると考えていました。「ストレージが完了しました」の下のコードの最後のセクション。配列の値をテストして印刷する何らかの形式の検証を印刷することになっていたので、割り当てようとしていたときにそこにある値を確認できました。

結局のところ、 Component 10の投稿のおかげで、しばらく脇に置いてコードを再分析したところ、間違いは外側のcoutステートメントを実行している空白に関連していることがわかりました。これにより、roIndexとcoIndexをどこでどのように使用したかを再分析し、forループでcoIndexが使用された理由を疑問視することになりました。そのとき私は、forループで使用した変数が、mazeRow文字列内の位置を決定し、coIndexが配列内の列を表すことに気づきました。これらを互いに混同しないでください。msamもこれをキャッチしました。

たとえば、mazeRow[ i ]とmaze[roIndex][ coIndex ]を使用します。

  1. mazeRow[ 0 ]は'。'です。そしてtrueはmaze[roIndex][ 0 ]に割り当てられます。i++とcoIndex++の両方をインクリメントします。
  2. mazeRow[ 1 ]は''であり、maze[][]には何も行われません。i++のみをインクリメントします。
  3. mazeRow [ 2 ]は'#'であり、falseはmaze[roIndex][ 1 ]に割り当てられます。i++とcoIndex++の両方をインクリメントします。

コンポーネント10で説明されているように、「余分な」数値の出所を理解し、自分の変数の使用法についての理解を深めると、残りはすぐに整理されました。この問題は、変数のローカルコピーとは何の関係もありませんでした。

私の現在のコードは次のとおりです:(ここで少し混乱して申し訳ありません-MAZEファイルには現在迷路の開始と目標を示すSとGがあります。)

Maze::Maze(int rows, int columns)
{
    string mazeRow="";
    bool maze[rows][columns];
    for (int i=0; i<rows; i++)
    {
        for (int j=0; j<columns; j++)
        {
        maze[i][j] = false;
        }
    }
    bool* target = NULL;
    ifstream input;
    input.open("MAZE",ios::in);
    if(input)
    {
        int roIndex=0; //Row Index
        while (getline(input, mazeRow))
        {
            //Testprint this row of the maze.
            cout << mazeRow << endl; //mazeRow is the data in that row of the text file.
            //Store each non-space value.

            int coIndex=0; //Column Index
            for (int i=0; i<mazeRow.length(); i++) //For each character in that row...
            {
                char check=mazeRow[i];
                target = &maze[roIndex][coIndex];   
                if (check=='.') //Path
                {
                    *target=true;
                    coIndex++;
                }
                else if (check=='#') //Wall
                {
                    *target=false;
                    coIndex++;
                }
                else if (check=='S') //Start
                {
                    *target=true;
                    coIndex++;
                }
                else if (check=='G') //Goal
                {
                    *target=true;
                    coIndex++;
                }
                else if (check==' ') //Space
                {
                    //ignore spaces
                }
                else //For all other cases, an invalid character is present.
                {
                    cout << "Invalid character detected." << endl;
                }
            }
        roIndex++;
        }
    }
    input.close();

    cout << "Storage completed." << endl;

    for (int i=0; i<rows; i++)
    {
        for (int j=0; j<columns; j++)
        {
        cout << maze[i][j] << " ";
        }
        cout << endl;
    }
    cout << "Verification completed." << endl;
}

これが将来誰かの助けになることを願っています。これを教訓にしましょう。問題をしばらく解決し、実行したすべてのことと実際に実行していることを分析することが最善の解決策になる場合があります。 。なぜあなたが物を持っているのか、そしてそれらが何のために使われる必要があるのか​​を知ってください。

于 2012-04-25T20:31:32.943 に答える
0

target = &maze[roIndex][coIndex];に応じてデータを設定してcoIndexいますが、サンプルデータにはスペースがあります。これらは「無視」されます (印刷されません) が、それでもインデックスをインクリメントするため、毎回配列内の値をスキップしています。

最初の反復セットmaze[0][0];

スペースがあるため、2回目の反復では何も設定されません

3 回目の反復セットmaze[0][2];

等...

maze[0][1];...などは決して設定されません

于 2012-04-25T09:25:04.427 に答える
0

すでに if(input) の値を保持しています。それらは bool maze[rows][columns]; に保持されます。if-else の後で完全にアクセスできます。迷路を再印刷する部分で、if-else の後でそれらにアクセスしています。

あなたの質問は、「他のメンバー メソッドの 1 つのメンバー メソッド (ctor) の値を保持する方法は?」 であるべきだと思います。これに対する答えは、配列をローカル変数ではなくメンバー変数に格納することです。

フレネルのアドバイスを心に留めてください。C++ には 2 次元配列はありません。配列の配列を持つことができます。それだけです。

class CMaze
{
   int m_Rows;
   int m_Columns;
   bool** m_arrarrMazeData;

public:
   CMaze(int rows, int columns)
   {
       m_Rows = rows;
       m_Columns = colums;
       //create array of pointers, each one will store another array
       m_arrarrMazeData = new bool*[rows];

      for (int i = 0; i<rows; i++)
      {
           //create new column for every row
           m_arrarrMazeData[i] = new bool[columns];
      }
    //rest of your code here, read into m_arrarrMazeData and forget about local variables, especially bool maze[rows][columns];

   }
}
于 2012-04-25T10:00:19.840 に答える
0

メンバー変数。


重大なアドバイス: ポインタ、メモリ アドレス、クラスなどに入る前に、まず基本的な C++ を学習してください。

于 2012-04-25T08:39:52.050 に答える
0

あなたがここで何を達成しようとしているのか、または実際にあなたが助けを得ようとしている問題が何であるかはわかりません.

期待どおりに動作していない行を強調表示しました。

 cout << *target << " "; //For some odd reason, this line BY ITSELF doubles up print. Ex. instead of printing 1 1 0 1 0, it would print 1 1 1 1 0 0 1 1 0 0.

ただし、この行はboolのみを出力しているため、次のように変更すると:

cout << "[" << *target << "] ";

それは与えます:

. # # # # # #  
1 [1] [254] 0 [0] [72] 0 [0] [0] 0 [0] [0] 0 [0] [77] 0 [0] [90] 0 [0] [0] [32] End of row.

これで、コードが読み込んだ行を出力し、その行を反復処理するため、文字が「.」の場合は最初に 1 を出力することがわかります。文字が「#」の場合は 0 ですが、それ以外の場合は値を割り当てないため1 [1] [254]、行の先頭にある は最初の「.」を読み取ります。文字 ( 1 [1]) とスペース ( [254])を無視する

(ブール値のマトリックスに初期値を割り当てるコードを公開していないことに注意してください。これを行っているかどうかはわかりませんが、このコードで必ずしも設定せずに、マトリックスの値を出力に使用していることは確かです。奇数の整数値について説明します。)

したがって、倍増するのではなく、あなたが要求したことを実行するだけです。おそらく、コードが条件付きでたどることができるすべてのパスを確認する必要がありますか?

于 2012-04-25T08:59:24.450 に答える