1

I'm building a simple family tree using classes, where each person has an ID and can have one or more relationships, and each relationship also has an ID. I'm trying to import this file in order to be able to use the class methods to import a tree:

9
Charless 
0 
F
2 5
Dianaaaa 
0 
M
1
William 
1 
M
6 
Harry 
1 
M
-1 
... 

For some context, the text file shows the number of people in the tree, name, son of relationship number X, gender, and ID of the person this person has a relationship with. If the person doesn't have any relationships, "-1" is shown. I'm incrementing the IDs automatically as I add a person or a relationship through the class methods. To import the file, I'm doing something like this:

ifstream f2;
f2.open("databasev2.txt");
string name; char gender;
int personrelationshipid; int sonofrelationshipid;
int numberOfPeople;
vector<int>relationships;
f2 >> numberOfPeople;
if (f2.is_open())
{ 
while (f2 >> name >> sonofrelationshipid >> gender )
{

    while (f2 >> personrelationshipid)
    {
        relationships.push_back(personrelationshipid);
        f2.ignore(0, ' '); 
    }
//...do something with the variables

My current problem is that the loop is stopping after the first iteration. I'm not sure if it's considering that the second name "Dianaaa" is no longer a string... Right now, it is reading "9", "Charless", "0", "F", "2" and "5", and inserting them into the vector, and then it stops. If I only have one relationship, this doesn't happen (i.e. if I remove the 5)

Moreover, I would like to add names with spaces between them - to do this, I think I just need to create a string and use f2.getline(name,string), then clear the buffer and remove the newline character so I don't have trouble reading the next line, am I right?

I can't use boost/JSON to serialize the information - I have to do this manually, so I would appreciate some help in "reinventing the wheel". However, I can edit the file as I want, adding some delimiters.

Thanks in advance

Paulo Maia
  • 63
  • 4
  • The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Dec 27 '16 at 13:18
  • I did use the debugger - that's how I found out it was reading the first line correctly and then exiting the program – Paulo Maia Dec 27 '16 at 13:31
  • 1
    I would think, that the second while loop is your problem. Could you reduce your file to 2 blocks and 1 relationship? Also try f2 >> personrelationshipid; without the while loop? – demonking Dec 27 '16 at 13:38
  • @demonking The problem is only if I have two relationships. The file gets read correctly with only one relationship. – Paulo Maia Dec 27 '16 at 13:48
  • Sorry, accidentally submitted the post and can't edit it - Using f2>>personrelationshipid didn't work - the same thing happens but now it doesn't insert both relationships into the relationships vector. – Paulo Maia Dec 27 '16 at 13:49

2 Answers2

2

You need to call f2.clear() every time a loop quits, because you use the stream as a boolean operand. Therefore when the loop quits, there are error flags which cause subsequent stream operations to fail.

FallenWarrior
  • 656
  • 3
  • 16
2

You need to clear the state of the file stream, with std::basic_ios::clear() function, inside the outer loop:

    while (f2 >> name >> sonofrelationshipid >> gender)
    {

        while (f2 >> personrelationshipid)
        {
            relationships.push_back(personrelationshipid);
        }

        if (!f2.eof())
            f2.clear();
alangab
  • 849
  • 5
  • 20