Problem in reading the first number from a line in file

Please support our C++ advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Mar 2008
Posts: 106
Reputation: guest7 is an unknown quantity at this point 
Solved Threads: 0
guest7 guest7 is offline Offline
Junior Poster

Problem in reading the first number from a line in file

 
0
  #1
Aug 10th, 2008
Hi,

I am trying to read the file (f1.txt) which contains :

3 0
-6 0
4 0
-8 0
...

I wish to read the first number from consecutive 2 lines and process them.

Following is my code:

---------------------------------------------------------------

std::vector<int> row;
std::vector<std::vector<int> > two_node;

int main()
{
string line1, line2;
int writetofile();

ifstream myfile ("f1.txt");
if(myfile.is_open())
{
while(! myfile.eof() )
{
getline (myfile, line1);
getline (myfile, line2);

row.push_back(line[0]);
row.push_back(line[1]);
two_node.push_back(row);
writetofile();
row.clear();
}
myfile.close();
}

else cout << "Unable to open the file \n";
return 0;
}

int writetofile()
{
ofstream file1;
file1.open("f2.imp",ios::app);
file1 << row[0] << " " << row[1] << " " << 0 << "\n";

file1.close();
return 0;
}

-----------------------------------------------------------------

My code is not working. I need the output in f2.imp as :

3 -6 0
4 -8 0
........

Thanks.
Last edited by guest7; Aug 10th, 2008 at 6:59 pm.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 3,844
Reputation: VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute VernonDozier has a reputation beyond repute 
Solved Threads: 503
Featured Poster
VernonDozier VernonDozier is offline Offline
Senior Poster

Re: Problem in reading the first number from a line in file

 
0
  #2
Aug 10th, 2008
3 0
-6 0
What do the zeroes represent? Data? A line termination flag? Will they always be zero or always the same or could they be like this?

3 2
-6 1
Your output shows this:

3 -6 0
so you are throwing out one of the four numbers. Which one? The lower right one?

Anyway, you need to figure out exactly what your data format is and what you want to keep and what you want to throw away. If it is two lines of two integers, you may want to just use the >> operator rather than the getline function. If you use getline, you may need to somehow extract the two integers from the string and throw one of them out. >> doesn't present that problem, nor would there be any potential conversion problems between char and int. I'm not sure you need to use strings or chars at all for this program, but I don't know what it's supposed to do besides what you've posted. You may just want to keep it as all integers.
Reply With Quote Quick reply to this message  
Join Date: Mar 2008
Posts: 106
Reputation: guest7 is an unknown quantity at this point 
Solved Threads: 0
guest7 guest7 is offline Offline
Junior Poster

Re: Problem in reading the first number from a line in file

 
0
  #3
Aug 10th, 2008
Hi,

In every line of the file there will be one integer and one zero always. i need to read the first integer and process that integer. I need to read the first integer of consecutive two lines and store them in a 2 Dimensional vector. Could you please provide me with a pseudo code of how to go about it.

Thanks
Reply With Quote Quick reply to this message  
Join Date: May 2008
Posts: 351
Reputation: Radical Edward has a spectacular aura about Radical Edward has a spectacular aura about Radical Edward has a spectacular aura about 
Solved Threads: 62
Radical Edward's Avatar
Radical Edward Radical Edward is offline Offline
Posting Whiz

Re: Problem in reading the first number from a line in file

 
0
  #4
Aug 10th, 2008
>What do the zeroes represent? Data? A line termination flag?
It doesn't matter. The requirement is only to process the first number on each line. Since none of the other numbers on the line aren't being processed, it's a safe assumption that they won't show up in the output.

>My code is not working.
You've got the right idea, it's just a matter of ironing out the details of your logic. First, this is how Edward would have done it:
  1. #include <iostream>
  2. #include <sstream>
  3. #include <stdexcept>
  4. #include <string>
  5. #include <vector>
  6.  
  7. int main()
  8. {
  9. using namespace std;
  10.  
  11. try {
  12. // Simulate a data file
  13. istringstream is("3 0\n-6 0\n4 0\n-8 0");
  14.  
  15. vector<int> data;
  16. string line;
  17.  
  18. // Save the first number on each line
  19. while (getline(is, line)) {
  20. istringstream numbers(line);
  21. int number;
  22.  
  23. // Try to extract the number
  24. if (!(numbers >> number))
  25. throw runtime_error("Expected a valid integer starting at '" + line + "'");
  26.  
  27. data.push_back(number);
  28. }
  29.  
  30. // Process the extracted data
  31. for (vector<int>::size_type i = 0; i < data.size(); i += 2) {
  32. cout << data.at(i);
  33.  
  34. // Assume an odd size isn't a fatal error
  35. // and only displays one processed number
  36. if (i + 1 < data.size())
  37. cout << ' ' << data.at(i + 1);
  38.  
  39. cout << " 0\n";
  40. }
  41. } catch (const exception& ex) {
  42. cerr << "Error processing data file: " + string(ex.what()) << '\n';
  43. }
  44. }
If you don't mind some constructive criticism, there are a few issues with your code that need to be addressed.
// Potential error!
while(! myfile.eof() )
This isn't a good way to control an input loop, especially when it comes to files. The contents of the file can affect the number of lines you try to read, and that number can be wrong. The canonical example of this is when reading lines and a file ends with a '\n' character. Here's a test program:
  1. #include <iostream>
  2. #include <sstream>
  3. #include <string>
  4.  
  5. int main()
  6. {
  7. using namespace std;
  8.  
  9. istringstream is1("line 1\nline 2\nline 3\n");
  10. istringstream is2("line 1\nline 2\nline 3");
  11. string line1;
  12. string line2;
  13.  
  14. cout << "Reading is1\n";
  15. while (!is1.eof()) {
  16. getline(is1, line1);
  17. cout << line1 << '\n';
  18. }
  19. cout << "Done reading is1\n";
  20.  
  21. cout << "Reading is2\n";
  22. while (!is2.eof()) {
  23. getline(is2, line2);
  24. cout << line2 << '\n';
  25. }
  26. cout << "Done reading is2\n";
  27. }
Notice how the first loop has an extra line at the end. That's the off-by-one error where the loop runs once more than it should. The only difference between is1 and is2 is a '\n' at the end. In is1, the last character is '\n' and getline terminates by successfully finding a delimiter; is1.eofbit is not set. In is2, the last character isn't '\n' and getline terminates by reaching end-of-file; is2.eofbit is set.

The underlying problem is that the eof() member function doesn't return true unless there's been an extraction attempt that has failed in a way that causes eofbit for the stream object to be set.

It's more accurate if you use the extraction operation itself. They typically return something you can test for success or failure. For example, getline returns the stream object, and in a boolean condition, the stream object can be immediately tested for failure conditions:
  1. #include <iostream>
  2. #include <sstream>
  3. #include <string>
  4.  
  5. int main()
  6. {
  7. using namespace std;
  8.  
  9. istringstream is1("line 1\nline 2\nline 3\n");
  10. istringstream is2("line 1\nline 2\nline 3");
  11. string line1;
  12. string line2;
  13.  
  14. cout << "Reading is1\n";
  15. while (getline(is1, line1))
  16. cout << line1 << '\n';
  17. cout << "Done reading is1\n";
  18.  
  19. cout << "Reading is2\n";
  20. while (getline(is2, line2))
  21. cout << line2 << '\n';
  22. cout << "Done reading is2\n";
  23. }
Now the correct number of lines are read regardless of what the last character is.
// Potential error!
getline (myfile, line1);
getline (myfile, line2);

// Won't do what you expect!
row.push_back(line1[0]); // Dies if line1 is empty
row.push_back(line2[1]); // Dies if line2 is empty
Ed highly recommends checking every single extraction attempt for failure. What happens if there isn't a second line? What happens if there aren't any lines but the eofbit isn't set? Right now you're just ignoring that situation and assuming that both lines always exist.

Another problem here is that line1[0] and line2[0] are characters, not the integers that you want. By pushing them onto the vector you're causing an implicit conversion from the numeric value of the character to integers. For Unicode or ASCII, that means the first two lines will give you 51 and 45 for line1[0] and line2[0], respectively. That's because the numeric value of '3' is 51 and the numeric value of '-' is 45.

What you need to do is get the integer representation of the strings "3" and "-6". Notice that -6 consists of two characters, by the way. A good standard way is to break out the stringstreams as in Edward's examples above.
Last edited by Radical Edward; Aug 10th, 2008 at 8:34 pm.
If at first you don't succeed, keep on sucking until you do succeed.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:




Views: 1272 | Replies: 3
Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC