Reputation: 3
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
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