2013-11-28 122 views
0

首先,我想說,這是對我的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 
+0

你怎麼知道它「似乎不正確..」?它似乎做了什麼?無關:這是什麼:'= {player1,player2,player3};'在'players'數組聲明的末尾進行操作?這不是必需的。 – WhozCraig

+0

當我說它不能正常工作時,我應該指定我的調試器顯示結構中的值沒有被正確更新。 此外,這是我學會初始化數組。爲什麼不需要? – shermanzach

+0

沒有看到'player1'等等......可以假定它不是必需的,但是如果他們簡單地被聲明爲'Quarterback player1,player2,player3;'或者其他一些,那麼它就不是必需的。數組中的那些四分衛對象將自行構建。但是我很好奇,你是否期待'player1'等等被你的閱讀代碼更新?如果是這樣,那肯定不會發生。你正在閱讀數組,而不是'playerN'對象,因爲你打算使用後者。 – WhozCraig

回答

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]; 
    } 
} 
+0

非常感謝提醒我命名。有時候我可能會很懶惰。 – shermanzach

1

什麼是不正確的與您的程序正常工作?

對於第二個事情循環有一個錯誤i < kNumGames而不是j < kNumGames

那麼你至少應該請檢查是否該文件被成功打開所有:

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

再有就是用線getline(myIF, temp);一個問題。它只會第一次工作,因爲第二次到達該行時,您的閱讀位置將位於您閱讀過的最後一個數字之後和換行符之前。這是第二個getline調用將返回一個空字符串,然後您將嘗試從玩家名稱中讀取數字。

您可以迅速修復,通過內部的for循環後加入getline(myIF, trash);

+0

欣賞關於檢查我的文件是否打開以及在循環中看到我的錯誤的提醒。程序變得越複雜,愚蠢的錯誤似乎越頻繁。 – shermanzach