-
reading fixed length
I'm reading from a file that is using fixed length entries:
Code:
Will Smith 25 Place Tulsa OK 38135
Corey Black Elm Street Dallas TX 89148
Tanner Hall Mount View Denver CO 52742
And, i have to rewrite the (>>) operator to read the fixed length fields.
My code:
Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Person
{
public:
char FirstName [11];
char LastName[11];
char Address [16];
char City [16];
char State [3];
char ZipCode [10];
Person();
};
Person::Person()
{
LastName[0] = 0;
FirstName[0] = 0;
Address[0] = 0;
City[0] = 0;
State[0] = 0;
ZipCode[0] = 0;
}
ostream & operator << (ostream & stream, Person & p)
{
stream << "First Name :" << p.FirstName << endl;
stream << "Last Name :" << p.LastName << endl;
stream << "Address :" << p.Address << endl;
stream << "City :" << p.City << endl;
stream << "State :" << p.State << endl;
stream << "ZipCode :" << p.ZipCode << endl;
stream << flush;
return stream;
}
istream & operator >> (istream & stream, Person & p)
{
stream.get(p.FirstName, 11);
stream.get(p.LastName, 11);
stream.get(p.Address, 16);
stream.get(p.City, 16);
stream.get(p.State, 3);
stream.get(p.ZipCode, 10);
return stream;
}
int main()
{
fstream inFile;
inFile.open("fixedlength.txt");
Person person1;
inFile >> person1;
cout << person1;
cout << endl;
cout << endl;
cout << person1.FirstName << "Test" << endl;
cout << person1.LastName << "Test" << endl;
cout << person1.Address << "Test" << endl;
cout << person1.City << "Test" << endl;
cout << person1.State << "Test" << endl;
cout << person1.ZipCode << "Test" << endl;
cout << endl;
cin.get();
cout << endl;
return 0;
}
So, i want the first 11 characters (including spaces) to be read into first name, the next 11 into last name and so on. For some reason they are not being read in correctly. The output looks like:
Code:
First Name :Will
Last Name : Smith
Address : 25 Place
City : Tulsa
State :
ZipCode : OK 3813
Will Test
Smith Test
25 Place Test
Tulsa Test
Test
OK 3813Test
As you can see, the spacing is messed up. The amount of spacing on the first name entry is 10 instead of 11 (one missing space). So, it looks like this space is being read into the next entry (last name), and that is why there is a space before smith. If i increase:
Code:
stream.get(p.FirstName, 11);
to
stream.get(p.FirstName, 12);
the output is even more messed up.
I originally tried:
Code:
stream >> p.FirstName;
stream >> p.LastName;
stream >> p.Address;
stream >> p.City;
stream >> p.State;
stream >> p.ZipCode;
but it wouldn't read in the spaces. Added stream >> noskipws; to that, and it didn't work right.
Basically i want to force it to read in the fixed amount, even if the characters are spaces.
Thanks.
-
Why don't you use the istream::read() function and pass the size you want to read?
The >> operator stops when it hits whitespace, which probably isn't what you want.
-
stream.get(p.FirstName, 11) reads 10, not 11, characters into p.FirstName, since the 11th character is the null character. Therefore a space is left in the input stream, and this space is then read by stream.get(p.LastName, 11). One way to solve this is to place a stream.ignore() after each call to get() so as to ignore the next character remaining in the buffer.
-
Thank you both. Works now.
-
Sorry, one more question.
I'm doing another program that is almost exactly the same, except it reads from a file using length indicators.
So, the input file looks like:
Code:
04Will05Smith0825 Place05Tulsa02OK0538135
05Corey05Black10Elm Street06Dallas02TX0589148
So, about everything is the same except:
Code:
istream & operator >> (istream & stream, Person & p)
{
int length = 0
stream >> length;
stream.get(p.FirstName, length);
stream.get(p.LastName, length);
stream.get(p.Address, length);
stream.get(p.City, length);
stream.get(p.State, length);
stream.get(p.ZipCode, length);
return stream;
}
So, i'm reading in the length indicator and reading that many characters into the appropriate place. The problem i am having is that i only want two digits to be read into length. Currently, it will read the number no matter how long it is. So, when it gets to the address:
It is reading in 825 into length, instead of 8.
So, i guess my question is, how can i get only two numbers read into "length" while still keeping it an int.
If there is a better way of doing this, let me know. My way seems to work fine, except for this problem.
By the way, I copied and pasted my earlier code, so the first bug has not been corrected in this post, but it has in my program.
Thanks