2015-04-19 49 views
1

我是一個非常新手的程序員,我試圖製作一個程序,讀取一個txt文件,其中包含5名學生的名字(僅限於第一名)以及四個考試分數學生。我試圖將名稱讀入名爲students的數組中,然後將分數讀入4個單獨的數組,名爲test1,test2,test3,test4,然後從監視器中顯示它。文件看起來像這樣:從txt文件中分離出平行數組

史蒂夫78 65 82 73

肖恩87 90 79 82

安妮92 90 89 96

卡羅爾72 65 65 60

凱西34 50 45 20

我很難與br消耗陣列並組織它們。有人能幫我嗎?請記住我是新手,所以我不知道有關編程的大量內容。

這是我的代碼至今:

#include <cstdlib> 
#include <iostream> 
#include <string> 
#include <fstream> 
#include <iomanip> 
#include <ctime> 
#define over2 "\t\t" 
#define over3 "\t\t\t" 
#define over4 "\t\t\t\t" 
#define down5 "\n\n\n\n\n" 


using namespace std; 



int main(int argc, char *argv[]) 
{ 


    ifstream inputFile; 


    //Constant for max string size 
    const int SIZE = 5; 


    //Constant for the scores 
    string names[SIZE], fileName, line, test1[SIZE], test2[SIZE], test3[SIZE], test4[SIZE]; 


    //input section, user enters their file name 
    cout << down5 << down5 << over2 << "Please enter your file name: "; 
    cin >> fileName; 
    system("CLS"); 




    //open the file containing the responses 
    inputFile.open(fileName.c_str()); 
    cout << endl; 

    //kicks you out if file isn't found 
    if (inputFile) 
    { 
     for(int i = 0; i < SIZE; i++) 
     { 
      getline(inputFile, line); 
      names[i] = line; 
      getline(inputFile, line); 
      test1[i] = line; 
      getline(inputFile, line); 
      test2[i] = line; 
      getline(inputFile, line); 
      test3[i] = line; 
      getline(inputFile, line); 
      test4[i] = line; 
     } 
      inputFile.close(); 
    } 
    cout << down5 << over3 << "Student\tTest1\tTest2\tTest3\tTest4\n"; 
    cout << over3 << "-------\t-----\t-----\t-----\t-----\n"; 
    for(int i = 0; i < SIZE; i++) 
    { 
     cout << over3 << names[i] << endl; 
     cout << over3 << test1[i] << endl; 
     cout << over3 << test2[i] << endl; 
     cout << over3 << test3[i] << endl; 
     cout << over3 << test4[i] << endl; 

    } 
    return 0; 
} 

回答

0

讓我們來看看你試圖讀取該文件的結構:

Steve 78 65 82 73 
Shawn 87 90 79 82 
Annie 92 90 89 96 
Carol 72 65 65 60 
Kathy 34 50 45 20 

數據的格式可以描述如下:

  • 每一行代表一個「記錄」。
  • 每個「記錄」包含多個列。
  • 列由空格分隔。

您目前正在使用getline()爲每

for(int i = 0; i < SIZE; i++) 
{ 
    getline(inputFile, line); 
    names[i] = line; 
    getline(inputFile, line); 
    test1[i] = line; 
    getline(inputFile, line); 
    test2[i] = line; 
    getline(inputFile, line); 
    test3[i] = line; 
    getline(inputFile, line); 
    test4[i] = line; 
} 

...而你真的想爲每個記錄一行閱讀和分裂它:

for (int i = 0; i < SIZE; i++) 
{ 
    string line; 
    size_t start = 0; 
    // For each line, attempt to read 5 columns: 
    getline(inputFile, line); 
    names[i] = get_column(line, start); 
    test1[i] = get_column(line, start); 
    test2[i] = get_column(line, start); 
    test3[i] = get_column(line, start); 
    test4[i] = get_column(line, start); 
} 

下面是您的原始代碼的修改版本,它將上述每行分開:

#include <cctype> 
#include <fstream> 
#include <iostream> 
#include <string> 

using namespace std; 

static string get_column(string line, size_t &pos) 
{ 
    size_t len = 0; 
    // Skip any leading whitespace characters. 
    while (isspace(line.c_str()[pos])) { ++pos; } 
    // Count the number of non-whitespace characters that follow. 
    while (!isspace(line.c_str()[pos+len]) && line.c_str()[pos+len]) { ++len; } 
    // Extract those characters as a new string. 
    string result = line.substr(pos, len); 
    // Update the "start" position (for the next time this function is called). 
    pos += len; 
    // Return the string. 
    return result; 
} 

int main() 
{ 

    const int SIZE = 5; 
    string names[SIZE], test1[SIZE], test2[SIZE], test3[SIZE], test4[SIZE]; 

    // Ask the user to enter a file name. 
    cout << "Please enter your file name: "; 
    string fileName; 
    cin >> fileName; 

    // Open the file and read the data. 
    ifstream inputFile(fileName.c_str()); 
    if (!inputFile.is_open()) { return 0; } 

    for (int i = 0; i < SIZE; i++) 
    { 
    string line; 
    size_t start = 0; 
    // For each line, attempt to read 5 columns: 
    getline(inputFile, line); 
    names[i] = get_column(line, start); 
    test1[i] = get_column(line, start); 
    test2[i] = get_column(line, start); 
    test3[i] = get_column(line, start); 
    test4[i] = get_column(line, start); 
    } 

    inputFile.close(); 

    // Display the data. 
    cout << "Student\tTest1\tTest2\tTest3\tTest4" << endl; 
    cout << "-------\t-----\t-----\t-----\t-----" << endl; 

    for(int i = 0; i < SIZE; i++) 
    { 
    cout << names[i] << "\t"; 
    cout << test1[i] << "\t"; 
    cout << test2[i] << "\t"; 
    cout << test3[i] << "\t"; 
    cout << test4[i] << endl; 
    } 

} 

運行程序產生下面的輸出:

Please enter your file name: textfile.txt 
Student Test1 Test2 Test3 Test4 
------- ----- ----- ----- ----- 
Steve 78 65 82 73 
Shawn 87 90 79 82 
Annie 92 90 89 96 
Carol 72 65 65 60 
Kathy 34 50 45 20 

注意,get_column()函數處理多個空格或太短的線條,讓這個文件:

Steve 78  65 82 73 
Shawn 87 90 
Annie 92 90 89 96 
Carol 72 
Kathy 34 50 45 20 

.. 。產生以下輸出:

Please enter your file name: textfile.txt 
Student Test1 Test2 Test3 Test4 
------- ----- ----- ----- ----- 
Steve 78 65 82 73 
Shawn 87 90 
Annie 92 90 89 96 
Carol 72 
Kathy 34 50 45 20 
+0

當我運行這個功能,它只是輸出隨機數字......這究竟是爲什麼會是什麼?另外,我非常新手,你的get_column函數對我來說絕對沒有意義。 :/ – Jameson

+0

get_column()函數接受一個字符串和一個「起始點」,並從它在「起始」點之後找到的第一組(非空白)字符中創建一個* new *字符串。如果你看到奇怪的結果,確保你在第一次調用之前將「開始」位置設置爲「0」;之後,開始位置由'pos + = len'線更新。要理解* how *的工作原理,請閱讀['isspace()'](http://pubs.opengroup.org/onlinepubs/009695399/functions/isspace.html)函數和['substr()']( https://msdn.microsoft.com/en-us/library/7w2119c6.aspx)方法。 – GoBusto

+0

哇,這非常有幫助。我不能夠感謝你! – Jameson

0

以前的答案是過度解決問題。你可以使用你的輸入文件流來檢索'格式化輸入'(也就是輸入你知道的格式,例如'string',然後是'int','int','int','int' )與>>操作符。

string name; 

int score[4]; 

ifstream mf; 

mf.open("score.txt"); 

// Get name string. 
mf >> name; 

// Get four score values into an array. 
mf >> score[0] >> score[1] >> score[2] >> score[3]; 

然後:

cout << name; 

cout << score[0]; 
cout << score[1]; 
cout << score[2]; 
cout << score[3];