【问题标题】:Reading from a file into an array of structs从文件读入结构数组
【发布时间】:2013-12-14 23:15:15
【问题描述】:

首先,我想说这是我的 CS161 课程的作业,所以虽然直接回答会很好,但很好的解释对我的帮助比什么都大。本周我们已经介绍了结构,但我的一些代码遇到了问题。我现在的程序目标是从名为“QBInfo.txt”的文件中读取三个结构的数组。

struct QuarterBack{
    string name;
    int completions[kNumGames];
    int attempts[kNumGames];
    int yards[kNumGames];
    int touchdowns[kNumGames];
    int interceptions[kNumGames];
};

QuarterBack players[kNumPlayers] = {player1, player2, player3};

另外,如果有帮助,我应该说 kNumPlayers 是一个设置为 3 的常数,而 kNumGames 是一个设置为 10 的常数。

这是我用来从文件中读取的代码。但它似乎无法正常工作,而且我一直不知道为什么,所以我想我可以向社区寻求帮助。

ifstream myIF;
    myIF.open("QBInfo.txt");
    string trash;
    string temp;
    getline(myIF, trash);
    for(int i = 0; i < kNumPlayers; i++){
        getline(myIF, temp);
        players[i].name = temp;
        for(int j = 0; i < kNumGames; j++){
            myIF >> players[i].completions[j];
            myIF >> players[i].attempts[j];
            myIF >> players[i].yards[j];
            myIF >> players[i].touchdowns[j];
            myIF >> players[i].interceptions[j];
        }
    }

这是我的导师提供的测试用例文件。第一个数字是任务的挑战部分,由于时间限制,我稍后将尝试。这就是我的循环开始之前代码的getline(myIF, trash) 部分的原因。

3
Peyton Manning              
27  42  462 7   0
30  43  307 2   0
32  37  374 3   0
28  34  327 4   0
33  42  414 4   1
28  42  295 2   1
29  49  386 3   1
30  44  354 4   3
25  36  330 4   0
24  40  323 1   0
Tom Brady               
29  52  288 2   1
19  39  185 1   0
25  36  225 2   1
20  31  316 2   0
18  38  197 0   1
25  43  269 1   1
22  46  228 0   1
13  22  116 1   1
23  33  432 4   0
29  40  296 1   1
Drew Brees              
26  35  357 2   1
26  46  322 1   2
29  46  342 3   1
30  39  413 4   0
29  35  288 2   0
17  36  236 2   1
26  34  332 5   0
30  51  382 2   2
34  41  392 4   0
30  43  305 1   1

【问题讨论】:

  • 你怎么知道它“似乎不能正常工作..”?它似乎在做什么?无关:这是什么:= {player1, player2, player3}; 在您的 players 数组声明的末尾做什么?不需要。
  • 当我说它不能正常工作时,我应该指定我的调试器显示结构中的值没有正确更新。另外,这就是我学会初始化数组的方式。为什么不需要它?
  • 没有看到player1 等...可能假设说它不需要,但如果它们被简单地声明为Quarterback player1, player2, player3; 或类似的,那么它就不需要.数组中的那些 Quarterback 对象将全部自行构建。但我很好奇,您是否期望 player1 等...被您的阅读代码更新?如果是这样,那绝对不会发生。您正在读取数组,而不是 playerN 对象,但您可能打算使用后者。

标签: c++ arrays struct io


【解决方案1】:

使用istringstream 使用从文件中读取的数据填充结构成员。 在这样的短程序中,命名可能不是特别重要——但考虑变量名来传达含义是一个好习惯。 数据文件的第一行似乎包含玩家人数。 getline 用于读取这一行。通常这将用于初始化玩家人数变量。

std::ifstream infile;
infile.open("qb.dat");
std::string nPlayers;
std::string playerName;

getline(infile, nPlayers);
getline(infile, playerName);

for (int player = 0; player < kNumPlayers; ++player)
{
  for (int game = 0; game < kNumGames; ++game)
  {
    std::string dataRow;
    getline(infile, dataRow);
    std::istringstream is(dataRow);
    is >> players[player].completions[game] >>
          players[player].attempts[game] >>
          players[player].yards[game] >>
          players[player].touchdowns[game] >>
          players[player].interceptions[game];
  }
}

【讨论】:

  • 非常感谢您提醒我命名。我有时会偷懒。
【解决方案2】:

您的程序到底有什么问题?

对于第二个 for 循环中的一件事,有一个错误 i &lt; kNumGames 而不是 j &lt; kNumGames

那么您至少应该检查文件是否已成功打开:

if( !myIF )
{
    // open failed
    return 1;
}

那么getline(myIF, temp);这行就有问题了。它只会在第一次工作,因为第二次到达该行时,您的阅读位置将就在您读入的最后一个数字之后和换行符之前。那就是第二个 getline 调用将返回一个空字符串,然后您将尝试从球员姓名中读取数字。

您可以通过在内部 for 循环后添加 getline(myIF, trash); 来快速解决此问题。

【讨论】:

  • 感谢有关检查我的文件是否打开以及在循环中看到我的错误的提醒。程序越复杂,愚蠢的错误似乎就越频繁。
猜你喜欢
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 2021-02-15
  • 1970-01-01
相关资源
最近更新 更多