0

I am trying to do this project for my c++ class in college, and I am having trouble reading a text file line by line, and then outputting the text from the file to the console. Here is the code I have:

void readFile()
{
 cout << "Reading Text File" << endl <<  endl;
 int huge, large, medium, small,  remainder; 
 string line0, line1, line2, line3, line4, line5, line6, numberOrdered;

ifstream fin;


fin.open("DoflingyOrder.txt");
while(getline(fin,numberOrdered))
{

    getline(fin, line1);
    cout << "Name: " << line1  << endl;

    getline(fin, line2);
    cout << "Street Address: " << line2  << endl;

    getline(fin, line3);
    cout << "City, State and Zip Code: " << line3  << endl;

    getline(fin, numberOrdered);
    cout << "Number of Doflingies Ordered: " << numberOrdered  << endl << endl;



}

It ignores the names in the text file, which mean it is a line off. Any suggestions? I can upload the text file and .cpp file to a dropbox if anyone need it.

Here is a sample of the text file:

Leslie Knope 1456 Plymouth Street Pawnee, IN 47408 356

Ann Perkins 217 Lowell Drive Pawnee, IN 47408 9

Tom Haveford 689 Lil Sebastian Avenue Pawnee, IN 47408 1100

There is NO SPACE before "Leslie Knope".

DJ Fries
  • 1
  • 1
  • 2
    What is the structure of the text file? Show a small sample of input data. – Eric J. May 03 '15 at 00:53
  • If you could show (at least a part of) your text file, and what happens when you read it (what does it mean that it is "a line off"?), it would help. And please, do NOT put it in Dropbox - paste it here. – Fabio says Reinstate Monica May 03 '15 at 00:53
  • What is the format of your file? Maybe it "ignores" the first line because that's the line you read in the first `std::getline` call in the `while` condition? – Some programmer dude May 03 '15 at 00:55
  • If the file content ended after only some of the variables were successfully read, there are no checks on the remaining `getline` calls to prevent printing out garbage. Try `for (int record_num = 0; getline(fin, numberOrdered); ++record_num) if (getline(fin, line1) && getline(fin, line2) && getline(fin, line3) && getline(fin, numberOrdered)) std::cout << ...; else { std::cerr << *record * << record_num << * is corrupt\n*; exit(1); }` - presumably, you should remove whichever `getline` for `numberOrdered` was accidental. – Tony Delroy May 03 '15 at 00:59
  • Added a sample of the text file. – DJ Fries May 03 '15 at 01:40

3 Answers3

1

The input you've finally posted...

Leslie Knope 1456 Plymouth Street Pawnee, IN 47408 356

Ann Perkins 217 Lowell Drive Pawnee, IN 47408 9

Tom Haveford 689 Lil Sebastian Avenue Pawnee, IN 47408 1100

...reveals all your getlines are wrong, as they read the entire line at a time (by default).

It's actually a fairly difficult/painful problem given "real world" data, for which a perfect solution's very difficult because some addresses might start with say a building name that's hard to distinguish from part of the person's name, and a multi-word town name would be hard to distinguish from the end of the earlier address details. A reasonable solution for educational use might be:

#define EXPECT(X) \
    do { \
        if (!(X)) throw std::runtime_error("EXPECT(" #X ")"); \
    } while (false)

std::string first, last;
std::string street, town_state_postcode;
int num;
std::string word;
while (fin >> first)
{
    EXPECT(fin >> last);
    while (fin >> word)
    {
        if (word[word.size() - 1] != ',')
            if (street.empty())
                street = word;
            else
                street += ' ' + word;
        else // trailing comma indicates town
        {
            town_state_postcode = word; // town
            EXPECT(fin >> word); // state
            town_state_postcode += ' ';
            town_state_postcode += word;
            EXPECT(fin >> word);
            town_state_postcode += ' ';
            town_state_postcode += word;
            EXPECT(fin >> numberOrdered);

            // SUCCESS use the data here
            // ...
        }
    }
}

The code above makes these simplistic assumptions:

  • the name consists of a first and last name

  • the town name is a single word with trailing comma

For a more-often accurate solution with real world data, you'd need to create lists of e.g. words that might terminate the "street" part of the address, such as "Drive", "Avenue", "Street", "Close" etc.. It would be massively better if you could get whatever created the text file to inject some separators into the data that communicate the structure (or even switch to something like XML).

Community
  • 1
  • 1
Tony Delroy
  • 94,554
  • 11
  • 158
  • 229
0
string line;
for(int i=0;;i++)
{
if(!getline(fin,line))break;
if(i%4==0)cout<<"Name: "<<line<<endl;
else if(i%4==1)cout<<"Street Address: " << line<< endl;
else if(i%4==2)cout<<"City, State and Zip Code: " << line << endl;
else  cout << "Number of Doflingies Ordered: " << line << endl << endl;
}
  • I just tried this and some of the output is correct, is some of them are correct. I really think the no space at the top of the file really makes this challenging since there are spaces in-between the other entries. – DJ Fries May 03 '15 at 02:17
-1

I would suggest using !eof() instead of getline(fin,numberOrdered) within your while loop since I believe that it is advancing the spot fin is at while not assigning it to anything thereby skipping the name column.