【问题标题】:values from text file not being written to 2D array?文本文件中的值未写入二维数组?
【发布时间】:2016-05-06 12:56:51
【问题描述】:

我正在尝试获取文本文件的值并将其加载到二维数组中。我遇到的问题是 char 变量的值似乎只覆盖了每个空白位置,我不知道为什么。

所以我打开了文件,我可以访问它来读取它的内容或在屏幕上显示它们,然后像​​这样设置我的二维数组:

    char chessBoards[BOARD_SIZE - 1][BOARD_SIZE - 1] = {{'A'}}; // All elements of 2D array initialized

    int x = 0; // line position - which line we are looking at
    int y = 0; // row position - which row we are looking at

在这个测试中,输出是所有 C 字符和一个 D 字符,我后来告诉它是这样的,所以我的问题似乎是文本文件的位置没有被复制到 char 变量中。

file.open(games);
        char point = 'Z';
        while (file.get(point))
        {
            for (int x = 0; x < BOARD_SIZE; x++)
            {

                for (int y = 0; y < BOARD_SIZE; y++)
                {
                    chessBoards[x][y] = point;
                }
            }

        }

        chessBoards[1][1] = 'D';
        cout << chessBoards[1][1];


        for (int x = 0; x < BOARD_SIZE; x++)
        {

            for (int y = 0; y < BOARD_SIZE; y++)
            {
                cout << "chessBoards[" << x << "][" << y << "]: ";
                cout << chessBoards[x][y] << endl;
            }
        }

但在这个变体中,除了一个“D”之外,每个值都是空白的

file.open(games);
        char point = 'Z';
        while (file.get(point))
        {
            for (int x = 0; x < BOARD_SIZE; x++)
            {

                for (int y = 0; y < BOARD_SIZE; y++)
                {
                    chessBoards[x][y] = 'C';
                }
            }

        }
        cout << chessBoards[1][1];


        for (int x = 0; x < BOARD_SIZE; x++)
        {

            for (int y = 0; y < BOARD_SIZE; y++)
            {
                cout << "chessBoards[" << x << "][" << y << "]: ";
                cout << chessBoards[x][y] << endl;
            }
        }

这告诉我它没有正确地从文件中获取值,但是在这个版本中,在顶部显示文件的内容没有问题。但是,如果我尝试将其他东西放在同一区域,它只会覆盖数组的第一个位置并停止。

    file.open(games);
    char point = 'Z';
    while (file.get(point))
    {
        for (int x = 0; x < BOARD_SIZE; x++)
        {

            for (int y = 0; y < BOARD_SIZE; y++)
            {
                chessBoards[x][y] = 'C';

            }

        }

        chessBoards[x][y] = 'C';
        chessBoards[x][y] = point;
        cout << point;

    }

    chessBoards[1][1] = 'D';
    cout << chessBoards[1][1]; 

【问题讨论】:

  • 您在循环外声明的xy 变量与嵌套fors 内声明的变量不同,它们的值保持0,所以在循环你基本上设置chessBoards[0][0] = point;。要实际读取文件,您应该将循环中的行更改为chessBoards[x][y] = point。然后监听 Paddy 并将数组声明为chessBoard[BOARD_SIZE][BOARD_SIZE]

标签: c++ arrays multidimensional-array char


【解决方案1】:

让我们从一行中的两个错误开始:

char chessBoards[BOARD_SIZE - 1][BOARD_SIZE - 1] = {{'A'}};

首先,您必须使用BOARD_SIZE不是BOARD_SIZE-1)作为您的维度。这将允许在 0 和 BOARD_SIZE-1 之间建立索引。您的循环中有未定义的行为。

由于您一直在注销数组的末尾,因此您可能会丢弃堆栈中的其他变量,并且任何事情都可能发生。像这样声明董事会:

char chessBoards[BOARD_SIZE][BOARD_SIZE];

其次,该初始化将每个元素初始化为'A'。它只初始化第一个元素,然后将所有其他元素归零。你想要std::fill_n(来自&lt;algorithm&gt;):

std::fill_n( (char*)chessBoards, BOARD_SIZE * BOARD_SIZE, 'A' );

或者只是memset(老派风格):

memset( chessboards, 'A', sizeof(chessBoards) );

现在是实际的棋盘读数。你一直在为每个角色重写整个棋盘。这意味着当您的while 循环最终完成时,板将包含读取的最后一个字符。这可能是一个新行,所以稍后输出板它会显示为空。

本质上,您是在循环的错误部分读取文件。改为这样做:

file.open( games );
if( file.is_open() )
{
    for( int x = 0; x < BOARD_SIZE; x++) 
    { 
        for (int y = 0; y < BOARD_SIZE; y++) 
        { 
            char point = 'C'; 
            if( !file.get( point ) ) 
                std::cout << "Error reading " << x << "," << y << std::endl; 
            chessBoards[x][y] = point;
        } 
    }
}

【讨论】:

  • 其实BOARD_SIZE并不是一个错误。我需要数组中总共 8 个位置(0 到 7),但在程序的另一个区域中,我需要准确的计数。此外,文件 IS 已打开。如果不是这样,我就无法将文本文件中的文本输出到屏幕上。除此之外,程序的这个区域是在检查它是否打开之后。我确实关闭并重新打开它,所以你看到的只是它第二次打开。尽管如此,我还是复制了那个小sn-p,正如预期的那样,它没有说“打开失败”,因为它是打开的。
  • 你误会了。如果你声明board[7][7],那么你只会得到从0到6的元素。除非BOARD_SIZE实际上是9。除非你显示一个实际的程序而不是sn-ps,否则很难评论可能发生的其他事情。也许您在没有意识到的情况下重新定义了某个范围内的变量,或者通过值而不是引用将file 传递给函数。
  • 实际上,我的第一个建议是您实际上修复了未定义的行为。这可能对您的程序做任何事情,包括在堆栈上丢弃东西(例如file 对象的内容)。你确实有未定义的行为。您声明了具有平方维度BOARD_SIZE-1 的数组,并且您正在访问BOARD_SIZE-1 的元素。这意味着在内存中,您将在数组末尾运行2*BOARD_SIZE-1 字节,重击堆栈中的所有内容。
  • BOARD_SIZE = 8。没错。如果一个数组有 8 个元素,它将是 0 到 5。这很好。我也试过你的其他sn-p。你拥有它的方式会产生一个编译错误“数组类型 char[7]' 是不可分配的。”和其他变体也好不到哪里去。
  • 老兄,char chessBoards[BOARD_SIZE][BOARD_SIZE]。故事结束。
【解决方案2】:

嗯,很明显,如果你从不写chessBoards[x][y] = point;,你就不能指望它加载分数。这适用于您的前 2 个 sn-ps(它们是相同的)。我假设您不小心将代码复制粘贴了两次,因为它们完全相同。这实际上很混乱。

你的第三个有xy 作为循环变量;在执行chessBoards[x][y] = point; 时,它们已超出范围。 看起来您声明了两次xy,一次在代码顶部附近,一次在for。如果是这样,你不应该写for (int y = 0; y &lt; BOARD_SIZE; y++);你可能想要for (y = 0; y &lt; BOARD_SIZE; y++) // note the missing 'int'

以下程序演示了该问题:

#include <iostream>

using namespace std;

int main()
{
    int x = 0;
    int y = 0;

    for(int x = 0; x < 2; x++) {
        for(int y = 0; y < 2; y++) {
            cout << "x: " << x << ", y: " << y << endl;
        }
    }

    cout << "\nx: " << x << ", y: " << y << endl;

    return 0;
}

这个输出:

x: 0, y: 0
x: 0, y: 1
x: 1, y: 0
x: 1, y: 1

x: 0, y: 0

显然,在 for 中重新声明 xy 是有问题的。我很确定这不是错误,因为它们在不同的范围内,但我不是 100% 了解这个特定的范围规则......主要是因为你对循环变量所做的事情没有意义在一个程序中。如果是我,我可能只是将chessBoards[x][y] = point; 放在内部循环中,因为我认为这就是你所追求的。

编辑添加:paddy 是正确的,如果你想要一个 8 元素数组,你需要像 array[8] 一样声明它,不是 array[7]

【讨论】:

  • 很抱歉。是的,我没有注意到它这样做了。我修复了第一个以显示我在做什么。关键是要说明我试图指出的问题。我会试试你的方法。一秒。
  • 好的,是的,chessBoards[x][y] = point;应该在内部循环中并且它不起作用。其他两个 sn-ps 的目的是显示我试图查明问题的内容。第二个 for 循环,顺便说一句,效果很好。
  • “第二个循环”是指第一个/第二个sn-ps中的第二个循环还是第三个sn-p中的唯一循环?
  • 正确声明数组会发生什么?另外,当您更改xy 时,输出有何变化?你的测试文件里有什么?
猜你喜欢
  • 2016-02-04
  • 1970-01-01
  • 1970-01-01
  • 2011-06-06
  • 2018-03-08
  • 2021-02-23
  • 2013-03-11
  • 1970-01-01
相关资源
最近更新 更多