2011-10-30 50 views
2

我在为我的CMPT类实验室分配时遇到了一些问题... 我正在尝试读取具有两个单词和一个字符串的文本文件每行数字,文件可以和任何人一样长。在.txt文件中逐字读取到C++中的结构

一个例子是

Xiao Wang 135798642 
Lucie Chan 122344566 
Rich Morlan 123456789 
Amir Khan 975312468 
Pierre Guertin 533665789 
Marie Tye 987654321 

我必须让每行一个独立的“学生”,所以我想用结构来做到这一点的,但我不知道该怎么做,因为我需要第一个,最后一个和身份证号码要分开。

struct Student{ 
    string firstName; 
    string secondName; 
    string idNumber; 
}; 

全部完成每个字分别都无法读取的尝试(结束了在阅读整个行,而不是)和我正在温和地沮丧。

在@Sylence的帮助下,我设法分别阅读每行。尽管如此,我仍然对如何用空白分割线条感到困惑。 ifstream中是否有分割函数? Sylence,是'部分'将是一个数组?我看到你有[]中的索引。 students.add(stud)究竟做了什么? 到目前为止我的代码是:

int getFileInfo() 
{ 
    Student stdnt; 
    ifstream stdntFile; 
    string fileName; 
    char buffer[256]; 
    cout<<"Please enter the filename of the file"; 
    cin>>filename; 
    stdntFile.open(fileName.c_str()); 
    while(!stdFile.eof()) 
    { 
     stdFile.getLine(buffer,100); 
    } 
    return 0; 
} 

这是我的修改,并最终getFileInfo的版本(),谢谢你沙赫巴兹,为方便,快捷的方式在数据读取。

void getFileInfo() 
{ 
    int failed=0; 
    ifstream fin; 
    string fileName; 
    vector<Student> students; // A place to store the list of students 

Student s;     // A place to store data of one student 
cout<<"Please enter the filename of the student grades (ex. filename_1.txt)."<<endl; 
do{ 
    if(failed>=1) 
     cout<<"Please enter a correct filename."<<endl; 
    cin>>fileName; 
fin.open(fileName.c_str());// Open the file 
failed++; 
}while(!fin.good()); 
while (fin >> s.firstName >> s.lastName >> s.stdNumber) 
    students.push_back(s); 
fin.close(); 
cout<<students.max_size()<<endl<< students.size()<<endl<<students.capacity()<<endl; 


return; 
} 

我现在困惑的是如何访问输入的数据!我知道它被放入一个向量中,但是如何访问向量中的单独空间以及向量中存储的输入数据的确切程度?如果我试图找出一个矢量的点,我得到一个错误,因为Visual Studio不知道输出什么我猜..

+0

对不起,链接到txt文件没有工作, – b3orion

+4

那么你有什么试图做?告诉我们你的努力,以便我们可以帮助你。 – Bart

+0

好吧..感谢您的快速回复。我很乐意向您展示我目前为止的内容,但我无法弄清楚如何在此评论框中设置代码的格式。我只是把撇号或[代码]或其他东西?抱歉无能力。 – b3orion

回答

2

其他答案很好,但看起来有些复杂。你可以这样做只是:

vector<Student> students; // A place to store the list of students 

Student s;     // A place to store data of one student 

ifstream fin("filename"); // Open the file 

while (fin >> s.firstName >> s.secondName >> s.idNumber) 
    students.push_back(s); 

注意,如果istream失败,例如当文件完成时,istream对象(fin)将评估为false。因此while (fin >> ....)将在文件结束时停止。

P.S.不要忘记检查文件是否打开。

+0

那么,我将如何去重复这个问题,以便整个文件中的行列表以及如何告诉它为每个迭代创建新的学生结构? ? – b3orion

+0

不错的解决方案:) @ b3orion你不需要为每个迭代创建一个新的对象,因为一个矢量使用了你给的数据的副本。 – Sylence

+0

好吧,所以我不需要每次都创建一个新学生,但是对于循环,我会只使用一个while循环吗?我只是混淆了如何告诉它每条迭代使用哪条线。就目前来看,没有循环,它只读取文件的最后一行。 – b3orion

0

只需读一整行,然后在空格处分割字符串,并分配值到结构的一个对象。

伪代码:

while(!eof) 
    line = readline() 
    parts = line.split(' ') 

    Student stud = new Student() 
    stud.firstName = parts[0] 
    stud.secondName = parts[1] 
    stud.idNumber = parts[2] 

    students.add(stud)  
end while 
+0

这实际上都是错误的(以很多方式)。请修复或我将downvote。 –

+1

我之所以写'伪代码'是有原因的...... – Sylence

+0

我对伪代码没有问题。但是你正在打破几个关键规则。 1)不要在一段时间内测试eof(适用于所有语言(因为在读过EOF之后才会发生EOF,这会导致循环进入额外的时间)2)不要使用新的回答C++的问题。 3)以很多语言进行空间分割是可以的,但实际上会导致你在C++中错误的路径 –

1

定义流阅读学生:

std::istream& operator>>(std::istream& stream, Student& data) 
{ 
    std::string line; 
    std::getline(stream, line); 

    std::stringstream linestream(line); 
    linestream >> data.firstName >> data.secondName >> data.idNumber; 

    return stream; 
} 

现在你应该能够从任何流流对象,包括文件:

int main() 
{ 
    std::ifstream file("data"); 
    Student   student1; 

    file >> student1; // Read 1 student; 

    // Or Copy a file of students into a vector 
    std::vector<Student> studentVector; 
    std::copy(std::istream_iterator<Student>(file), 
       std::istream_iterator<Student>(), 
       std::back_inserter(studentVector) 
      ); 
} 
+0

这究竟是如何工作的?你能给代码添加一些评论吗? – b3orion

+0

由于这是作业,我认为如果你为自己细节而努力会更好。如果你将这些信息与@Shahbaz答案结合起来,那么你应该有你需要的所有细节。 –

+0

但是代码@Shahbaz是否已经输入读入Student的文本?为什么我需要流媒体阅读器?尽管如此,我很困惑如何访问每个学生。我如何选择每个学生,因为它把它们放在一个矢量中...... – b3orion