2011-09-02 82 views
1

为什么这段代码不想加载文本文件中的所有值?它只能正确加载第一个对象的项目,但之后它开始变得奇怪。下面是代码:从文本文件中加载对象数据

#include <iostream> 
#include <fstream> 
#include <cstdlib> 

using namespace std; 
class Location 
{ 
public: 
    Location() 
    { 
     locName = "No Name"; 
     locDesc = "No Description"; 
     locID = 0; 
    } 

    friend ostream& operator <<(ostream& outs, const Location & showMe) 
    { 
     // keeping output same as input... 
     outs << showMe.locName << endl; 
     outs << showMe.locDesc << endl; 
     outs << showMe.locID << endl; 

     return outs; 
    } 

    friend istream& operator >>(istream& ins, Location & inLoc) 
    { 
     getline(ins, inLoc.locName); 
     getline(ins, inLoc.locDesc); 
     ins >> inLoc.locID; 

     return ins; 
    } 

private: 
    string locName; 
    string locDesc; 
    int locID; 
}; 

int main() 
{ 
    ifstream inFile; 

    inFile.open("loc_data.txt"); 
    if (inFile.fail()) 
     { 
      cout << "\nCould not open the input file!"; 
      exit(1); 
     } 

    Location fileLoc[10]; 
    int i = 0; 

    while (inFile.good()) 
     { 
      inFile >> fileLoc[i]; 
      i++; 
     } 

    for (int j = 0; j < 10; j++) 
     cout << fileLoc[j]; 

    return 0; 
} 

输入文件是:

Town Hall 
Main venue for functions 
1 
City Park 
Outdoor venue 
2 
Train Station 
Commuting point 
3 
Local Airport 
Long distance travel 
4 

,输出是:

Town Hall 
Main venue for functions 
1 

City Park 
0 
No Name 
No Description 
0 
No Name 
No Description 
0 
No Name 
No Description 
0 
No Name 
No Description 
0 
No Name 
No Description 
0 
No Name 
No Description 
0 
No Name 
No Description 
0 
No Name 
No Description 
0 

我有一个suspucion即函数getline负责这一点,但不知道足以确定,但我真的很想知道为什么会发生这种情况,而不仅仅是“修复”。

+0

你有文件是什么?你怎么知道哪个字段在哪里结束? – Jagannath

回答

2

你的第一个问题是,这行不提取换行符:

ins >> inLoc.locID; 

这意味着,在第二Locationgetline1后提取行的其余部分 - 即一个空字符串 - 名字。

这意味着您很快就会与您想要阅读的行不同步。

你也应该考虑改变你的while循环,因为在你提取一个新位置之前,你检查流是否“好”,但是你不检查提取是否成功,你认为提取是有效的。

+0

事实上,在ins >> inLoc.locID解决它之后,添加一个char temp变量,然后使用ins.get(temp)。 – georgelappies

+0

@georgelappies:或者你可以使用'ins.get()'或'ins.ignore()'来忽略一个字符或者'ins.ignore(std :: numeric_limits :: max(),' \ n')'忽略到下一个换行符的所有内容。 –

1

这工作:

#include <iostream> 
#include <fstream> 
#include <cstdlib> 
#include <sstream> 

using namespace std; 
class Location 
{ 
public: 
    Location() 
    { 
     locName = "No Name"; 
     locDesc = "No Description"; 
     locID = 0; 
    } 

    friend ostream& operator <<(ostream& outs, const Location & showMe) 
    { 
     // keeping output same as input... 
     outs << showMe.locName << endl; 
     outs << showMe.locDesc << endl; 
     outs << showMe.locID << endl; 

     return outs; 
    } 

    friend istream& operator >>(istream& ins, Location & inLoc) 
    { 
     getline(ins, inLoc.locName); 
     getline(ins, inLoc.locDesc); 
     std::stringstream ss; 
     std::string s; 
     getline(ins, s); 
     ss << s; 
     ss >> inLoc.locID; 

     return ins; 
    } 

private: 
    string locName; 
    string locDesc; 
    int locID; 
}; 

int main() 
{ 
    ifstream inFile; 

    inFile.open("loc_data.txt"); 
    if (inFile.fail()) 
     { 
      cout << "\nCould not open the input file!"; 
      exit(1); 
     } 

    Location fileLoc[10]; 
    int i = 0; 

    while (inFile.good()) 
     { 
      inFile >> fileLoc[i]; 
      i++; 
     } 

    for (int j = 0; j < 10; j++) 
     cout << fileLoc[j]; 

    return 0; 
} 
1

我相信这个问题是这一行:插件>> inLoc.locID;

问题是,当您使用>>操作符读取此值时,它将在缓冲区中留下下一行字符,这会导致读取循环结束(如果您逐步浏览它,可以看到)。

为了解决这个问题,我认为你需要故意从缓冲区中清空这个字符,或者使用getline,并将输入(验证我希望!)转换为字符串中的数字。

希望这有助于