Click to See Complete Forum and Search --> : Some strange problem about operator >>


walkinginwater
November 30th, 2004, 05:21 PM
I want to write an programme to read the datas from a file;
The data is stored as the following form
273 834 454 728 4774
138 520 303 479 44875
309 322 186 372 64181
..... .... ....
I only need the 1st,2nd, 4th number in one row, each line I will produce two new numbers
My first problem is that the wrong version of my program can compile, can build, but it cannot do anything, the Output.txt is zero size, that means the program is terminate at while(input>>temporal), but I am sure even in the wrong version the “test.data” is opened

My second problem is that in the wrong version, when I substitute statement “while(input>>temporal)”, by while(!input.eof()) and the data acquire statement “input>>temporal” inside the loop, the program can compile, can build, but when I run it, it is in a horrible situation, it cannot stop the loop, it cannot end,


//wrong version
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

int main(int argc, char* argv[])
{
ifstream input("test.data");
ofstream output("Output.txt");
const int HISTO2DSZ=256;
int temporal,x,y,e1,e2;
int Num_input=0;//this take counts of the input number

while(input>>temporal)//run-time error, the condition “input>>temporal” is not satisfied at the beginning
{
Num_input++;
if ((Num_input%5)==1)
x=temporal;
if((Num_input%5)==2)
y=temporal;
if((Num_input%5)==3)
e1=temporal;
if((Num_input%5)==4)
{
e2=temporal;
double xc,yc;
xc = ((double)x/e2);
yc = ((double)y/e2);
output<<xc<<" "<<yc<<endl;
}
}
}

//correct one

#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

int main(int argc, char* argv[])
{
ofstream output("Output.txt");
ifstream input("test.data");
int x,y,e1,e2;
double ts;

while (!input.eof())
{
input >> x >> y >> e1 >> e2 >> ts;
double xc,yc;
xc = ((double)x/e2);
yc = ((double)y/e2);
output<<xc<<" "<<yc<<endl;
}


}

HighCommander4
November 30th, 2004, 09:04 PM
You could use an std::istream_iterator to read the data into an std::vector<int>. That is proven, tested code, and is much less likely to cause errors. Then you can do your operations using the data in the vector. Tell me if you need help with doing this.

walkinginwater
December 1st, 2004, 07:39 AM
Hi, HighCommander:

I am sorry I reply so later. i am now in germany, and i post it yesterday night,so untill now i see your post

i only have two problem about your advice:
the first one are: my data file is very large, there are 100,000 lines in my file , if you read them all into the std::vector<int>, that will cause memory problem or not ? If it not happen , please tell me how to handle it, Thank you first!

the second is that , you don't answer why the problem is coming, ? can you give me some hints_

Philip Nicoletti
December 1st, 2004, 08:26 AM
Verify that the input file exixts (if on Linux ... filename are case sensitive).
(is the extansion .dat or .data ?)


ifstream input("test.data");

// verify file opened ...

if (!input)
{
cout << "could not open file\n";
return 0;
}

walkinginwater
December 1st, 2004, 09:07 AM
the following is my test function in the programme.

assure(input,"test.data");

void assure(std::ifstream& in,
const std::string& filename = "") {
using namespace std;
if(!in) {
fprintf(stderr, "Could not open file %s\n",
filename.c_str());
exit(1);
}
}

HighCommander4
December 1st, 2004, 04:46 PM
I don't see anything wrong with your code. Maybe something is wrong with the file, such as it does not contain the right data or something. If you send me your entire code (including the file, or at least the first part of the file), I can test it and I might be able to figure out what is happening.

As for your concern about memory, std::vector uses memory allocated from the heap so it should have no problem storing 100,000 integers.

Paul McKenzie
December 1st, 2004, 04:52 PM
Also, if you know you will be storing a lot of items in the vector, you should call std::vector::reserve() to allocate enough memory so that adding items to the vector will not cause too much of a bottleneck:

#include <vector>

int main()
{
// Slow
{
std::vector<int> V;
for (int i = 1; i <= 100000; ++i )
V.push_back(i);
}

// Faster
{
std::vector<int> V;
V.reserve(100000);
for (int i = 1; i <= 100000; ++i )
V.push_back(i);
}
}

Regards,

Paul McKenzie

cma
December 1st, 2004, 10:31 PM
The one where you have while (!input.eof()) is incorrectly detecting EOF. This is a relatively common mistake for beginners (and for the experienced sometimes), you can't detect end of input this way, you have to first check if the stream entered a failed state first and then check for end of input (prefererably after every input):

bool done_reading_file = false;

while (not done_reading_file)
{ input >> x >> y >> e1 >> e2 >> ts;
if (input.fail())
{ // input stream is in a failed state, no need to continue reading
done_reading_file = true;
if (not input.eof())
cerr << "Error reading file, got some bad input" << endl;
}
else
{ double xc,yc;
xc = ((double)x/e2);
yc = ((double)y/e2);
output << xc << " " << yc << endl;
}
}


How you have it, it goes into an infinite loop because if you read in something that makes the stream go into a failed state (like trying to read strings into int vars. or the file doesn't exist), end of input is never reached, so you then have an infinite loop, the stream is in a failed state but it's not because of EOF.

The alternative to introducing a boolean variable to terminate the loop is to just to read the data in the loop declaration:

while (input >> x >> y >> e1 >> e2 >> ts)
{
double xc,yc;
xc = ((double)x/e2);
yc = ((double)y/e2);
output<<xc<<" "<<yc<<endl;
}

This will continue reading data until the stream enter's a fail state, either because of EOF or because of bad input.

walkinginwater
December 2nd, 2004, 06:33 AM
thanks for your help!
the problem which predict by cma does happen !!! But there are precondition
The precondition is that the number of the data stored in the "test.data" is not exactly five per line, it will go to infinitly loop!

i have already past the full source code and "test.data" into an email box

"studing_data_cpuls_transfer@yahoo.com "
password "walkinginwater"

if you have intersting, you can go to check!

walkinginwater
December 2nd, 2004, 07:14 AM
I am sorry to say that : i made a very silly mistake
HighCommander4 is right, i made somemistakes about the data file, the datas in the files are not all integers, the five one is a double one, when "temporal" is declared type "double", everything works now!
Thank you everybody!