user3216905
user3216905

Reputation: 3

Two functions working with getline on same fstream object c++

I have the following problem. I have these two functions. The first one is reading contact information from a txt file, contacts separated by the symbol '#' like this-

//sample txt file
#1
Name: AAA
Phone: 08782634
Phone: 0245637
Date: 23.34
Phone: 324324324
#2
Name: BBB
Phone: 99999

and it finds the length of each contact(number of lines between every '#'). The second one calls the first one and then the contact should be printed, but it prints the second contact, not the first.

Is it possible that getline from the first function changes the stream somehow, because the second function works perfectly when I use it without the first (hardcored capacity to a const int)?

int Contact::FindNumberOfFields(std::ifstream& in)
{
    char* buffer = new char [1024];
    int cnt = 0;
    int i = 0;
    int pos = 0;
    while(in)
    {
        in.getline(buffer, 1024);
        if (strchr(buffer, '#'))
        {
            while (in.getline(buffer, 1024))
            {
                if (!strchr(buffer, '#') && strlen(buffer))
                {
                    cnt++;
                }
                else
                {
                    return cnt;
                }
            }


        }
    }
    in.clear();
    in.close();
    delete [] buffer;
}

void Contact::ReadContactFromStream(std::ifstream& in)
{
    SetCapacity(FindNumberOfFields(in));
    // cout << GetCapacity() << endl; // output is five, correct
    while(in)
    {
        if (addedFields >= GetCapacity()) // works correct when addedFields >= hardcored int (5) and removing SetCapacity(in) from code
        {
            break;
        }
        contactTypes[addedFields] = CreateObjectFromLine(in);
        addedFields++;
    }

}

Upvotes: 0

Views: 273

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409442

All files have a "current read position", and as you read from the file that position is advanced. Unless you change the position you will always read the next thing in the file, which at the moment "#2" is the next record.

My suggestion for you to solve it, is to simply have one function which reads data, and when it comes to a new record marker then it initializes an empty vector of strings, and read the lines of the record into this vector, and then pass this vector on to a function which parses the contents.

Something like the following pseudo code:

std::getline(stream, line);
for (;;)
{
    if (line is start of record)
    {
        std::vector<std::string> current_record;
        while (std::getline(stream, line))
        {
            if (line is start of record)
                break;  // Break out of inner loop
            else
                current_record.push_back(line);
        }

        parse_record(current_record);
    }
}

Upvotes: 1

Related Questions