从文件中读取行到一组数组

时间:2017-11-03 19:54:12

标签: c++ arrays

我目前的任务是创建一个从文件中获取信息并将其存储到一组数组中的函数。第一个数组是一维数组,存储学生的名字,而第二个数组是一个二维数组,存储几个测试的值。文件中输入文本的示例如下:

Jon 81 83 77 90
Amanda 80 91 95 93
Sarah 78 81 11 90
Aaron 92 83 44 69
Blair 23 45 96 38
Clark 60 85 45 39
Kenney 77 31 52 74
John 93 94 89 77
Sammy 79 85 28 93
Glenn 85 72 49 75
Brad 74 65 49 96

第一个数组名为studentNames [],仅存储名称。第二个数组是studentGrades [] []并存储四个测试的成绩。到目前为止,我已经在这个项目上运行了大约一百万个圈子。我认为我有一个很好的方法从文件中获取信息,但我无法弄清楚如何从每行中获取值。

int main()
{
    ifstream fileIn ("grades.txt");
    string line;

    for (int i = 0; i < 11; i++)
    {
        getline(fileIn, line);
        int lineLen = line.length();
        cout << line << " Length = " << lineLen << endl;
    }

    return 0;
}

这将显示行,但我无法弄清楚如何获取存储在数组中的片段的实际值。我知道这个问题的措辞可能很差,但我想弄清楚如何恰当地说出来。如果可以,我会更新更多信息。

上面的代码给出了这个输出:

Jon 81 83 77 90 Length = 15
Amanda 80 91 95 93 Length = 18
Sarah 78 81 11 90 Length = 17
Aaron 92 83 44 69 Length = 17
Blair 23 45 96 38 Length = 17
Clark 60 85 45 39 Length = 17
Kenney 77 31 52 74 Length = 18
John 93 94 89 77 Length = 16
Sammy 79 85 28 93 Length = 17
Glenn 85 72 49 75 Length = 17
Brad 74 65 49 96 Length = 16

如果我将线条添加到主体:

string names[11];

然后将其添加到循环中:

fileIn >> names[i];
cout << names[i];

我最终在输出中没有任何变化。但是,如果我注释掉显示行的其他cout语句,我会得到以下输出:

Amanda Sarah Aaron Blair Clark Kenney John Sammy Glenn Brad

首先,迭代器“i”应该从0开始,但它忽略了列表中的第一个名字。现在,如果我保留原始注释,只需将名称[i]添加到输出中:

cout << line << " Length = " << lineLen << names[i] << endl;

我最终得到了:

Jon 81 83 77 90 Length = 15Amanda
 80 91 95 93 Length = 12Sarah
 78 81 11 90 Length = 12Aaron
 92 83 44 69 Length = 12Blair
 23 45 96 38 Length = 12Clark
 60 85 45 39 Length = 12Kenney
 77 31 52 74 Length = 12John
 93 94 89 77 Length = 12Sammy
 79 85 28 93 Length = 12Glenn
 85 72 49 75 Length = 12Brad
 74 65 49 96 Length = 12

作为输出。所以它是从行的前面删除名称并将它们粘在上面的行的后面。在所有情况下,列表中的名字都会被忽略。

编辑: 为了澄清,我一直在研究这个问题三天,我目前正在尝试重新创建过去几天所采取的步骤,这样我就可以展示我所做的以及我遇到的行为。尝试重新创建这些步骤是一个耗时的过程。

2 个答案:

答案 0 :(得分:1)

只需使用while(file >> s >> f1 >> f2 >> f3 >> f4){}而不使用getline

getline会读取您在这种情况下不想要的整行。

int main()
{
    ifstream file("file");

    const int capacity = 11;
    string names[capacity];
    float grades[capacity][4]; //<-- 4 is enough
    float average[capacity];

    string s;
    int counter = 0;
    float f1, f2, f3, f4;
    while(file >> s >> f1 >> f2 >> f3 >> f4)
    {
        //test this:
        cout << s << ", " << f1 << ", " << f2 << ", " << f3 << ", " << f4 << "\n";
        names[counter] = s;
        grades[counter][0] = f1;
        grades[counter][1] = f2;
        ...
        //calculate average...
        average[counter] = (f1 + f2 ...)/4;
        counter++;

        //the array holds 11 items only
        //break in case there are more than 11 valid lines in the file
        if (counter == capacity)
            break;
    }
    ...
}

istream >>运算符将跳过空白行并读取下一个项目。请注意,如果您使用"Jon Green 81 83 77 90"之类的内容,则此代码将无效,因为"Jon Green"由空格分隔。如果有名称和姓氏,则需要2 >>个运算符用于文本。或者您需要将getlinestd::stringstream

等其他选项结合使用

答案 1 :(得分:1)

@Ernesto:我想举例说明它如何与数组一起使用。在这个例子中我不想使用任何STL类,所以这段代码只是为了显示,你如何从字符串中获取元素:

先决条件:每行有5个项目除以空格 -

#include <iostream>
using namespace std;

#define ARRSIZE 5

string split(string &str) {
    string item;

    // look for the first space-char
    size_t found = str.find_first_of(" ");

    // if there are still space-chars found
    if (found != string::npos) {
        // get the item
        item = str.substr(0, found);

        // update the str (+1 because of the space-char
        str = str.substr (found+1);
    } else {
        // getting the last item
        item = str;
        // update the str one last time
        str = "";
    }

    return item;
}

int main() {
    string str = "Jon 81 83 77 90";
    string arr[ARRSIZE];
    int arrInd = 0;
    while(str.length() > 0) {
        arr[arrInd++] = split(str);
    }

    for(int i = 0; i < ARRSIZE; ++i)
        cout << arr[i] << endl;
}