2

我目前在 C++ 方面的背景是我已经参加了一个学期的大学课程。

我很难弄清楚如何使我在 if-else 语句中分配的值保留在它之外。我想如果我事先在外面声明它并使用指针自己处理内存地址,这将是公平的游戏,但显然不是。

我现在的“迷宫”文件:

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

这就是我在 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

您已经保留了 if(input) 中的值。它们被保留在 bool maze[rows][columns] 中;并且在 if-else 之后完全可以访问。您在 if-else 之后访问它们,在您重新打印迷宫的部分。

我认为您的问题应该是“如何为其他成员方法保留一个成员方法(ctor)的值?”。这个问题的答案是将数组存储在成员变量而不是本地变量中。

将phresnel的建议铭记于心。C++ 中没有二维数组。您可以拥有数组数组,仅此而已。

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

您正在设置数据target = &maze[roIndex][coIndex];coIndex但在您的示例数据中有空格。这些是“忽略”(未打印),但您仍会增加索引,因此您每次都在跳过数组中的一个值:

第一次迭代集maze[0][0];

第二次迭代没有设置任何内容,因为您有空间

第三次迭代集maze[0][2];

ETC...

maze[0][1];...等永远不会设置

于 2012-04-25T09:25:04.427 回答
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

我不确定您在这里要达到什么目的,或者实际上您要寻求帮助的问题是什么。

您突出显示了一条未按预期执行的行:

 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 << "[" << *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 回答
0

成员变量。


严肃的建议:在学习指针、内存地址、类等之前先学习基本的 C++。

于 2012-04-25T08:39:52.050 回答