Jump to content
  • Advertisement
Sign in to follow this  
blueloon

C++ File I/O while loop won't read till end of file

This topic is 4101 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This program reads in two .txt files, manipulates the numbers in them and outputs the result to the screen. the output is accurate but the problem is that both input files are 200+ pages long but the output is only about a hundred lines. If I delete the first few pages of one of the input .txt files and run the program again, I get different output but it still only continues for about 100 lines. the int res is just a feature where the numbers in each file won't be considered if their corresponding timestamps aren't within a few minutes of each other, and the program compares the next line in one file with the same line in the other file. here's example input from corrected.txt: 73.1817322 -145.9081573 20070323065959 73.1817169 -145.9082642 20070323071000 73.1817322 -145.9084015 20070323071958 and from walrus.txt 73.106343 -145.724085 20070317170032 73.106340 -145.724090 20070317170033 73.106363 -145.724057 20070317170034 and here's the program: #include <fstream> #include <iostream> #include <math.h> using namespace std; int main() { double longs1, longs2, lat1, lat2, time, referencetime, distance; double pi, dtor, hdlat, hdlon, rearth, small, dist, bear; pi = 3.141592653589793; dtor = pi/180.; rearth = 6356752.3; small = 0.00000000000001; int res = 120; ifstream in ("corrected.txt"); ifstream in2 ("walrus.txt"); cout << "timestamp" << " " << "distance (m)" << " " << "bearing (degrees from true north)" << '\n'; cout.precision(14); while (! in.eof()){ in >> lat1 >> longs1 >> referencetime; while (! in2.eof() ) { in2 >> lat2 >> longs2 >> time; //compute distance between 1 and 2 using haversine formula double latr = (lat1-lat2)*dtor; double longr = (longs1-longs2)*dtor; double a = asin(sin(latr/2)*sin(latr/2)+cos(lat1*dtor)*cos(lat2*dtor)*sin(longr/2)*sin(longr/2)); double c; if (a < 0) { c = sqrt(1-a); } else { c = sqrt(a); } double d = 2*rearth*c; bear = sin((90-lat2)*dtor)*sin((longs2-longs1)*dtor)/(sin(d)+small); bear = asin(bear); if (lat2 < lat1) { if (longs1 < longs2) bear = pi-bear; if (longs2 < longs1) bear = 0-pi-bear; } bear = bear/dtor; if (time < referencetime+res && time > referencetime-res) { cout << time << " " << d << " " << bear << '\n'; break; } else { } } } return 0; }

Share this post


Link to post
Share on other sites
Advertisement
well, what happens is you read a value from the first file, in. Then you read every value from in2 and compare it against in until in2 reaches the end of file. Then you go back and read the next value from in. After that you enter the while loop only to find out that you are still at the end of the file. Yup, you never reset your position to the beginning of the file. That's probably your culprit.

Share this post


Link to post
Share on other sites
Quote:
Original post by nobodynews
well, what happens is you read a value from the first file, in. Then you read every value from in2 and compare it against in until in2 reaches the end of file. Then you go back and read the next value from in. After that you enter the while loop only to find out that you are still at the end of the file. Yup, you never reset your position to the beginning of the file. That's probably your culprit.


hmm, judging by initial test runs it would instead scan in2.txt until a timestamp within the resolution was found, then bump down to the next line in both in.txt and in2.txt and do likewise until eof, not repeatedly go through the entire in2.txt for every line in in.txt. shouldn't the break in

if (time < referencetime+res && time > referencetime-res) {

cout << time << " " << d << " " << bear << '\n';
break;
}

break the inner while loop?

Share this post


Link to post
Share on other sites
Dont use while( !fstream.eof() ), as the end of file flag is only set *after* you read the end of the file. Prefer instead:


while (in >> lat1 >> longs1 >> referencetime){
while (in2 >> lat2 >> longs2 >> time ) {
// etc ...
}
}



Note this forms primitive error checking too (did we read 3 objects successfully?).

Share this post


Link to post
Share on other sites
Quote:
Original post by blueloon
Quote:
Original post by nobodynews
well, what happens is you read a value from the first file, in. Then you read every value from in2 and compare it against in until in2 reaches the end of file. Then you go back and read the next value from in. After that you enter the while loop only to find out that you are still at the end of the file. Yup, you never reset your position to the beginning of the file. That's probably your culprit.


hmm, judging by initial test runs it would instead scan in2.txt until a timestamp within the resolution was found, then bump down to the next line in both in.txt and in2.txt and do likewise until eof, not repeatedly go through the entire in2.txt for every line in in.txt. shouldn't the break in

if (time < referencetime+res && time > referencetime-res) {

cout << time << " " << d << " " << bear << '\n';
break;
}

break the inner while loop?


I didn't see that break statement, my mistake

edit: I still stand by my original response, mostly... I'm sure the reason you aren't getting a large output is because your conditions are too rare to occur. That is, the odds of two time stamps being that close together are pretty slim.

Look at the text file itself and do what the computer does, except only look at the time stamps. It reads the first time stamp from 'in' and then goes through 'in2' until it finds a time stamp within 120 minutes of 'in'. But there probably aren't many entries from 'walrus.txt' that are +-120 of 20070323065959 and the ones that Are... are probably near each other. Also, do the time stamps always increase, or is there some backtracking going on?

Think of this simple example where we check for +- 0.5:
position: 1    2    3    4    5    6    7    ...  48     ...  3481 (end)
file 1: 0.6, 2.5, 2.8, 3.1, 3.9, 4.0, 4.6, ..., 203.9, ... 54.1
file 2: 0.8, 0.9, 100, 130, 161, 192, 193, ..., 2.8, ..., 200


Read in values form position 1 in both files, Match! Go to position 2, no match, so increase position of file 2. No match, increase position of file 2. No matches until file 1 is in position 2 and file 2 is in position 48 when file 1 finally goes to position 3. Eventually, file 2's position will be at 3481, but because it only found, say, 50 matches file 1 is only in position 50. Because file2 is in eof state, it never enters the inner while loop and you never compare anything again.

I don't know what you're actually hoping to achieve so I can't tell what you should change.



[Edited by - nobodynews on June 26, 2007 8:45:23 PM]

Share this post


Link to post
Share on other sites
In the currently empty else part, you could output info about the data, that was not considered. Let's say: time, referencetime, res. Write it to another out stream or mark the then two types of output with different starting signs for easy scanning. That way you would better see what the filtering really does and then decide what needs to be fixed.

Share this post


Link to post
Share on other sites
Quote:
Original post by nobodynews
or is there some backtracking going on?


thanks for your help everybody, I've found the source of error and it wasn't the program. there was indeed some backtracking happening in the timestamps of one of the input files. this wasn't expected. basically, everything runs smooth when time moves forward top to bottom in both input files but the output stops when a timestamp jumps to an earlier value. luckily, fixing bugs in the input file algorithms isn't my problem!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!