【问题标题】:Filling array from file won't work从文件填充数组不起作用
【发布时间】:2014-01-28 18:50:59
【问题描述】:

我已经制作了一个“地图”数组,并试图从一个“地图”文件中填充它。创建时,我将值“0”分配给数组的每个元素,但“地图”文件包含以下内容:

地图:

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

我使用 'loadMap()' 加载地图

加载地图():

void room::loadMap()
{
    int x=0;
    int y=0;
    string line;
    ifstream mapFile(NAME + "_MAP.txt");

    while(!mapFile.eof())
    {
        for(int i=0; i<cellsY; i++)
        {
            getline(mapFile,line,'\n');

            for(int j=0; j<cellsX; j++)
            {
                getline(mapFile,line,' ');
                map[(cellsX*j) + cellsY] = atoi(line.c_str());
            };
        };
    }

    y = 10;
    x = 15;
    for(int i=0; i<y; i++)
        {
            cout << endl;
            for(int j=0; j<x; j++)
            {
                cout << map[(x*j) + y];
            };
        };
}

在此示例中,元素仍分配给“0”,但我正在尝试模仿地图文件布局。

【问题讨论】:

  • 在 StackOverflow 中搜索“正在读取文件 eof”。
  • 你为什么使用getline?这看起来是使用 file &gt;&gt; variable 的好案例。
  • 你的文件真的打开了吗?
  • @ThomasMatthews 外部循环中的getline 是合理的,如果他想确保每一行都在单独的行上。不使用他在外循环中读到的那行不太好。并且像他那样使用getline,然后是atoi,也不是一个好主意。 (更不用说getline( mapFile, line, ' ' ) 会一直读取到下一个空格,并且不会在换行符处停止。)

标签: c++ arrays file io


【解决方案1】:

对于初学者,您永远不会测试任何输入是否有效,也不会 即打开成功。然后,在外循环中,您阅读 文件中的一行,然后将其丢弃,然后再进一步阅读 在内循环中。而且你的指数计算是错误的。

您可能正在寻找类似的内容:

std::ifstream mapFile(...);
if ( !mapFile.is_open() ) {
    //  Error handling...
}
for ( int i = 0; mapFile && i != cellsY; ++ i ) {
    std::string line;
    if ( std::getline( mapFile, line ) ) {
        std::istringstream text( line );
        for ( int j = 0; j != cellsX && text >> map[cells X * i + j]; ++ j ) {
        }
        if ( j != cellsX ) {
            //  Error: missing elements in line
        }
        text >> std::ws;
        if ( text && text.get() != EOF ) {
            //  Error: garbage at end of line
        }
    }
}

对于错误处理,最简单的就是输出一个 适当的错误消息并继续,注意错误,以便您 最后可以返回某种错误代码。

【讨论】:

  • 出于好奇,为什么不用mapFile &gt;&gt; value 而不是getlineistringstream
  • 因为输入格式要求(或似乎要求)每行一行; mapFile &gt;&gt; value 将接受任何cellsX * cellsY 值序列。如果没问题,当然,删除getline 将是最简单的解决方案。
  • 我相信我会放弃 getline .. 仍在解决问题 atm
  • @ThomasMatthews 主要问题是索引问题。我刚刚了解了模拟数组,谢谢您的帮助。我删除了一些东西,我使用 mapFile >> value 方法。
【解决方案2】:

我想这就是你要找的。​​p>

void room::loadMap()
{
   int x=0;
   int y=0;
   ifstream mapFile(NAME + "_MAP.txt");

   for(int i=0; i<cellsY; i++)
   {
      for(int j=0; j<cellsX; j++)
      {
         int v;
         mapFile >> v;
         if ( mapFile.eof() )
         {
            break;
         }
         map[(cellsX*j) + cellsY] = v;
      }
   }

   y = 10;
   x = 15;
   for(int i=0; i<y; i++)
   {
      cout << endl;
      for(int j=0; j<x; j++)
      {
         cout << map[(x*j) + y];
      };
   };
}

【讨论】:

  • while (!mapFile.eof()) 肯定是错误的。 (人们从哪里得到这样的想法?)
  • 感谢@JamesKanze 指出错误。修改了代码。
  • if ( mapFile.eof() ) 仍然是错误的。 (就像在这里简单地使用 break 一样。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-12
  • 2018-01-19
  • 1970-01-01
相关资源
最近更新 更多