动态分配的数组在输出时丢失ifstream数据

时间:2017-04-04 00:09:33

标签: c++

我正在处理一个代码,该代码读取包含" course"的文件。赛道的位置,需要确定球场的高度和宽度。示例课程如下:

xxxxXxxxxXxxxxXxxxxXxxxxXxxxxX
xxxxxx      xxxxx      xxx  xx
xxxxx        xxx       xx    x
xx     xx     x        x     x
X      xx              x  x  x
x      xx                 x  x
x      xxxxxxxxxxxxxx     x  x
x     xxxxxxxxxxxxxxxxxxxxx  x
xFFFF x  xxxxxxxxxxxxxx      x
XFFFF x    xxxxxxxx          x
x     x      1               x
xxxxxxx      2        xxx    x
xxxxxx       3         x     x
x                            x
Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

现在因为数组在编译时需要常量值,而我无法提供,我尝试在检索高度和宽度值后动态地将数组分配给内存。总之,我的代码看起来像这样:

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

using namespace std;

struct Level {
    int HEIGHT;
    int WIDTH;
};

vector<Level> getRowCol(istream& fin) {

    vector<Level> level;

    fin.seekg(0, fin.end);
    int fileSize = fin.tellg();
    fin.seekg(0, fin.beg);

    string s;
    if (getline(fin, s)) {
        Level l;

        l.WIDTH = s.size();
        l.HEIGHT = fileSize / (l.WIDTH + 1);

        level.push_back(l);
    }

    return level;
}

void readCourse(int& cols, int& rows, istream& fin) {

    char** level = new char*[rows];
    for (int i = 0; i < cols; i++) {
        level[i] = new char[cols];
    }

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            level[i][j] = 0;
        }
    }

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            fin.get(level[i][j]);
        }
    }

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cout << level[i][j];
        }
    }
}


int main(int argc, char** argv) {
    vector<Level> course;
    ifstream fin(argv[1]);

    course = getRowCol(fin);

    cout << course[0].WIDTH << " columns" << endl;
    cout << course[0].HEIGHT << " rows" << endl;

    readCourse(course[0].WIDTH, course[0].HEIGHT, fin);

    return 0;
}

通过命令行传递文件时此代码的输出如下所示:

31 columns
14 rows
xxxxxx      xxxxx      xxx  xx
xxxxx        xxx       xx    x
xx     xx     x        x     x
X      xx              x  x  x
x      xx                 x  x
x      xxxxxxxxxxxxxx     x  x
x     xxxxxxxxxxxxxxxxxxxxx  x
xFFFF x  xxxxxxxxxxxxxx      x
XFFFF x    xxxxxxxx          x
x     x      1               x
xxxxxxx      2        xxx    x
xxxxxx       3         x     x
x                            x
Xxxxxxxxxxxxxxxxxx

现在似乎存在差距。如果在编译时间之前声明const int值,则不会出现这些间隙。但是,在脚本运行不足以使用动态分配之前,我无法想到使用未知值构建数组的另一种方法。

还有另一种或更好的方法来实现这一目标吗?

1 个答案:

答案 0 :(得分:0)

您的第一个业务订单是调用getRowCol(),它以相当迂回的方式尝试事先确定文件中地图的大小。它通过确定文件的大小,然后倒回到文件的开头,读取第一行,获取其长度,以及从该计算中计算行数来实现。

然而,如果你非常小心地注意,你会意识到当getRowCol()返回时,它会在>读取文件的第一行后执行。但是下面的代码假定它从文件的开头读取,并读取整个地图。当然,这不会再发生了,因为文件中的第一行已被阅读。

这解释了你问题的第一部分,缺少了一行和一个空白。

就问题的第二部分而言:所有这些复杂的逻辑肯定是完全的,完全没必要的。

您的代码表明您对矢量的工作方式有基本的了解和理解。

那么,为什么首先需要这种复杂的逻辑?

只需打开文件,然后将文件的每一行读入一个向量中,push_back()读取后的每一行,直到文件结束。

完成所有操作后,矢量的大小就是地图的高度。因为向量包含文件中每行的一个值。通过查看每一行的大小,您就可以知道地图的宽度。

就是这样。可能有十几行代码,而且不多于此。比你在这里展示的更简单,更容易理解。您现有的逻辑(获取文件大小,获取第一行的大小,然后将其分开)是非常脆弱的。如果由于某种原因,文件中的行具有不同的长度(可能其中一些具有一些尾随空格),则计算结果将完全关闭。有了这个更简单的方法,处理这种错误情况变得更加容易,并且仍然会产生一些有意义的结果。