C ++,逐行读取文本文件后得到向量中的错误

时间:2016-01-04 12:55:21

标签: c++ file-io visual-studio-2015

这是我想做的事,

在逐行读取文本文件并拆分每一行时,我想检查ID(第一个)是否等于我想要的ID。如果它等于,则将该行的其余部分放入除ID之外的向量中。

文本文件(示例):

11111 Mark 100 40 30
11112 Helen 90 50 20
11113 John 20 20 80
11114 Paul 50 40 10
11115 Hank 10 10 20

到目前为止,这是我的代码,但由于某种原因,我得到一个“向量下标超出范围”错误。

#include...

using namespace std;



vector <string> Grades;

void getgrades(string x) {
    string gtemp;
    ifstream myfile;
    myfile.open("Test.txt");
    while (getline(myfile, gtemp)) {
       stringstream ss(gtemp);
       string ToBe;
       while (getline(ss, ToBe, ' ')) {
          Grades.push_back(ToBe);
        }
        if (Grades[0] != x) {
          Grades.clear();
        }
        else {
         Grades.erase(Grades.begin());
        }
  }
}


int main() {
    string x;
    cout << "Enter the ID: ";
    cin >> x;
    getgrades(x);
    cout << "Name:" << Grades[0] << endl;
    cout << "Grades: " << Grades[1] << " " << Grades[2] << " "<< Grades[3] <<endl;



  return 0;
}

p.s:我正在使用VS2015。

4 个答案:

答案 0 :(得分:3)

找到正确的线后,不要退出外线。

因此外部while循环继续,并且由于下一行与ID不匹配,您的向量将被清除。因此,当您尝试访问任何元素时,您必然会失去boudns。

要纠正完成您的代码,请按以下步骤操作:

 ...
 else {
     Grades.erase(Grades.begin());
     break; //<============ exit the outer while
    }

但有一个建议:您永远无法确定用户是否输入了有效的ID。在任何情况下,您应该在尝试访问它们之前验证向量中有多少元素(如注释中建议的那样)。

答案 1 :(得分:1)

你的逻辑错了。

F.e。您输入了ID = 11111,然后在第一个&#39; while(getline(myfile,gtemp))&#39; 循环后,您将在您的“等级”中输入此内容。矢量:

成绩[0] =马克

成绩[1] = 100

成绩[2] = 40

成绩[3] = 30

在此之后,下一个&#39; while(getline(myfile,gtemp))&#39; 将清除你的等级向量,因为等级[0] =标记,它是&#39; s不再等于x

答案 2 :(得分:0)

您在找到ID后继续阅读,并清除下一个ID上的向量,将其留空。

当您找到x并收集其成绩时,您可以立即中断。

你也不需要为每个人收集成绩并清除它们,你可以跳过你不感兴趣的行(并且全局变量很糟糕,mmkay?):

vector<string> getgrades(string x) {
    vector<string> grades;
    string line;
    ifstream myfile("Test.txt");
    while (getline(myfile, line)) {
        stringstream ss(line);
        string id;
        if (ss >> id && id == x)
        {
            string grade;
            while (ss >> grade) {
                grades.push_back(grade);
            }
            break;
        }
    }
    return grades;
}

答案 3 :(得分:-1)

你应该在擦除后返回,否则你将获得垃圾值。