why does it loop once too many times?

August 5, 2009 at 08:29:51
Specs: Windows XP
can somebody look at this and tell me why it loops once extra when reading back from the saved files?


void WeatherStation::SaveToFile()
{
fstream OutFile(FileName.c_str(), ios::out);
for(int K = 0 ; K < Station.size() ; K++)
{
OutFile << Station[K] << endl;
OutFile << Agents[K] << endl;
OutFile << Temp[K] << endl;
OutFile << Highs[K] << endl;
OutFile << Lows[K] << endl;
}
OutFile.close();
}

void WeatherStation::ReadFromFile()
{
fstream InFile(FileName.c_str(), ios::in);
string Buffer;
double Bufferint;

while(!InFile.eof()) //Check to see if you're at the end of the file...
{

getline(InFile, Buffer);
cout << "Buffer1 = " << Buffer << endl;
Station.push_back(Buffer);//storing information
getline(InFile, Buffer);
cout << "Buffer2 = " << Buffer << endl;
Agents.push_back(Buffer);
InFile >> Bufferint;
cout << "Buffer3 = " << Bufferint << endl;
Temp.push_back(Bufferint);
InFile >> Bufferint;
cout << "Buffer4 = " << Bufferint << endl;
Highs.push_back(Bufferint);
InFile >> Bufferint;
cout << "Buffer5 = " << Bufferint << endl;
Lows.push_back(Bufferint);
InFile.ignore(100, '\n'); //Flush the buffer after a numeric input...
}


See More: why does it loop once too many times?

Report •


#1
August 5, 2009 at 08:57:46
while(!InFile.eof()) //Check to see if you're at the end of the
file...

This does not do what the comment describes. You don't
know that you are at the end of the file until you actually try to
read past the end and fail.

Compare that with the old Pascal idiom which is similar to
what you have here. In Pascal, when you check for eof(), the
runtime tries to read a character from the file "behind the
scenes" and tells you if it is at the end. If it is not at the end,
it saves that character in a buffer, and returns it next time you
ask to read a character from the file.

C and C++ don't have this look-ahead feature. You need to
recode your function so that it checks the values returned by
getline. (Or check with eof() after calling getline.)


Report •

#2
August 5, 2009 at 09:03:34
can i still use these vector lists to do that?
or do i need to change my whole program?
or do you know if theres a code i can just replace with?
btw.
thanks for replying!

Report •

#3
August 5, 2009 at 09:12:38
What "vector lists"? All you need to change is function
ReadFromFile, I see neither vectors nor lists in there. You can
keep the same local variables. To make the logic easier to
understand, you might want to write an additional function (pass
it the fstream as an argument) that reads one record from the file
and returns a boolean to tell you whether it's succeeded or not.
You can then call the new function in the while loop.

Report •

Related Solutions

#4
August 5, 2009 at 09:21:39
so im looking to do something with pascal kind of?

Report •

#5
August 5, 2009 at 09:24:54
im looking at a tutorial that talks about posttesting and while loops which is i think a during loop?
for this function, do you think it would be more efficient/effective to do one during or after?

Report •

#6
August 5, 2009 at 09:33:02
Replace:
while(!InFile.eof()) //Check to see if you're at the end of the file...
{

  getline(InFile, Buffer);

With:

while (getline(InFile, Buffer)) {


Report •

#7
August 5, 2009 at 09:43:37
oh thanks so much!
just to make sure i understand what changed is you tested it before instead of waiting till after to see if it was the end?

Report •

#8
August 5, 2009 at 09:56:49
I moved the getline() into the while. So long as your istream biased object remains in a good state, you'll get back a != 0 number. When the read fails, presumably because you hit the EoF, ios::operator void*() returns 0. This reads as false, and you exit the while loop.

Report •

#9
August 5, 2009 at 10:01:20
that makes sense thanks!

Report •

#10
August 5, 2009 at 10:12:55
is there a way to make it not double up if you type in save again?

Report •

#11
August 5, 2009 at 10:25:27
is there a way to make it not double up if you type in save again?
What now?

Report •

#12
August 5, 2009 at 10:28:04
i have a program that saves to a file
but when i type in save again
it double its up
etc.
my input is
bob
frank
and when i save once it saves as
bob
frank
but when i save it again it saves double
bob
frank
bob
frank

Report •

#13
August 5, 2009 at 11:09:41
You're probably opening the output file as append. Instead, try adding the trunc flag.

Report •

#14
August 5, 2009 at 19:15:48
for my save to file i use

fstream OutFile(FileName.c_str(), ios::out);
and for reading back in i use
fstream InFile(FileName.c_str(), ios::in);
i tried putting in the trunc part
but it didnt do anything
thanks for responding though!


Report •

#15
August 5, 2009 at 20:22:18
If fstream OutFile(FileName.c_str(), ios::out | ios::trunc) doesn't work, your best option would probably be to just delete the file before opening it.

While we're on the subject, you ARE opening it when you do your save function, and then closing it at the end of the function, aren't you?


Report •

#16
August 5, 2009 at 20:27:49
opening and closing as in what?
i put my input it, save the program, read the file i saved, and usually just quit after that.
however if not, i put my input in, save the program, read the file i saved, save the program again, read it again (which is where hte error is) and then quit

Report •

#17
August 5, 2009 at 21:24:13
Open and close the output file. You ARE doing that in your save function, and not your constructor and destructor, correct?

Report •

#18
August 6, 2009 at 09:04:24
yes
thats in my save file

Report •

#19
August 6, 2009 at 09:37:09
Then you'll have to delete the file before you (re)open it. This is platform dependent.

On Windows, the code looks like this (be sure to #include <Windows.h>):

if (!::DeleteFile(FileName.c_str())  && ::GetLastError() != ERROR_FILE_NOT_FOUND)
  std::cerr << "Unable to delete file" << std::endl;

On POSIX, the function is unlink(FileName.c_str()), found in #include <unistd.h>


Report •

#20
August 6, 2009 at 10:01:13
You shouldn't have to delete the file, as long as you are open it with ios::out | ios::trunc. In your original code, you were just passing ios::out. You need to pass ios::trunc too.

Report •

#21
August 7, 2009 at 06:47:12
thanks!
you guys were really helpful!!

Report •


Ask Question