Thread: Think I have a getline problem....

  1. #1
    Registered User
    Join Date
    Mar 2003
    Posts
    32

    Unhappy Think I have a getline problem....

    My output is coming out very odd, essetially my program does the following, opens two files and inputs the strings of each file for the following variables:
    function function2
    partnerName partnerName2
    partnerId partnerId2
    equipType equipType2
    equipNumber equipNumber2
    counter dateTime2
    dateTime

    I use a fin.ignore() and fin.getline (dateTime, 30) since the date will have spaces.

    This works fine when inputing from the first file, but does not input the information correctly from the second file. I checked the steps in which each file is written to and created and they are identical.

    This is my code, you'll notice alot of uncessary couts in there,I use to try and find where I am going wrong. I think its a getline problem but I've used this in a similar fashion before????
    # include <fstream.h>
    # include <string.h>
    # include <stdlib.h>

    int main ()
    {
    //list variables for input and output
    char function [9];
    char partnerName [30];
    char partnerId [11];
    char equipType [15];
    char equipNumber [7];
    int counter;
    char function2 [9];
    char partnerName2 [30];
    char partnerId2 [11];
    char equipType2 [15];
    char equipNumber2 [7];
    int counter2;
    char dateTime [30];
    char dateTime2 [30];
    int stopBit = 0;
    int stopBit2;


    //open files for input of information
    ifstream fin;
    fin.open ("G:\\HEHP\\HVMDATALOGOUT.txt", ios::in | ios::nocreate | ios::eofbit);
    if (fin.fail ())
    {
    return EXIT_FAILURE;
    }

    //do

    while (!fin.eof () && (stopBit <1))
    {
    //input from Check Out log file
    fin >>ws;
    fin >> function;
    fin >> partnerName;
    fin >> partnerId;
    fin >> equipType;
    fin >> equipNumber;
    fin >> counter;
    fin.ignore ();
    fin.getline (dateTime, 30);
    cout<< function<<endl;
    cout<< partnerName<<endl;
    cout<< partnerId<<endl;
    cout<< equipType<<endl;
    cout<< equipNumber<<endl;
    cout<< counter<<endl;
    cout<< dateTime<<endl;
    cout <<"**************************************"<<endl ;
    ifstream fin2;
    fin2.open ("G:\\HEHP\\HVMDATALOGIN.txt", ios::in | ios::nocreate | ios::eofbit);
    if (fin2.fail ())
    {
    return EXIT_FAILURE;
    }
    stopBit2 = 0;
    while ((strcmp(equipNumber, equipNumber2)!=0) && (!fin2.eof()) && (stopBit2<1))
    {

    //input from Check In log file
    fin2 >> ws;
    fin2 >> function2;
    fin2 >> partnerName2;
    fin2 >> partnerId2;
    fin2 >> equipType2;
    fin2 >> equipNumber2;
    fin2.ignore ();
    fin2.getline (dateTime2, 30);
    fin2 >>ws;
    cout <<function2<<endl;
    cout <<partnerName2<<endl;
    cout <<partnerId2<<endl;
    cout <<equipType2<<endl;
    cout <<equipNumber2<<endl;
    cout <<dateTime2<<endl;
    cout <<"##############################################" <<endl;
    if ((strcmp(equipNumber, equipNumber2)!=0))
    {
    if (fin2.eof())
    {
    stopBit2 =1;
    ofstream fout;
    fout.open ("G:\\HEHP\\HVMDATALOGOUT2.txt", ios:ut | ios::app);
    if (fout.fail ())
    {
    cout <<"Unable to open file HVMDATALOGOUT2.txt"<<endl;
    return EXIT_FAILURE;
    }
    cout<<"writing to the data2 file"<<endl;
    cout <<function<<endl;
    cout <<partnerName<<endl;
    cout <<partnerId<<endl;
    cout <<equipType<<endl;
    cout <<equipNumber<<endl;
    cout <<counter<<endl;
    cout <<dateTime<<endl;

    fout <<function<<" "<<partnerName<<" "<<partnerId<<" "
    <<equipType<<" "<<equipNumber<<" "<<counter<<"\n"
    <<dateTime<<endl;

    fout.close();
    fin2.close();

    }
    }
    else if ((strcmp(equipNumber, equipNumber2)==0))
    {
    cout <<"Match found !!!!!!!!!!!!!!!!!!!!!!!!!"<<endl;
    fin2.close ();
    }

    };
    if (fin.eof())
    {
    stopBit = 1;

    fin.close();
    return EXIT_SUCCESS;
    }

    };
    fin.close();


    }
    I'd like to put Murphy and his laws in headlock sometimes!

  2. #2
    Registered User
    Join Date
    Nov 2002
    Posts
    1,109

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    First, read the FAQ about using code tags when posting code, it will make it much easier for someone else to read when they decide they may want to help, and others will decide not to help because they code is too dificult to read like this. It's almost impossible to keep track of {} in this type of code.

    Second, your use of ignore() and getline() is technically correct, although may be inappropriate for this particular file based on the exact way the file is set up. If there is more than one white space between counter and dateTime fields, the ignore won't work, and if there isn't a newline char after the end of the dateTime field, then you may be asking for trouble too.


    I think the problem is with the construction of the loops. I can't be sure because the indenting doesn't allow me to readily correlate {}s. You should only declare fin2 once. The folowing lines seem to do it everytime throughthe loop. This means you are only ever going to get the first set of data in the second file being read in over and over.
    Code:
    ifstream fin2;
    fin2.open ("G:\\HEHP\\HVMDATALOGIN.txt", ios::in | ios::nocreate | ios::eofbit);
    if (fin2.fail ())
    {
      return EXIT_FAILURE;
    }
    stopBit2 = 0;
    The same goes for fout. Declare it outside the loop, just once!


    >>what's with ws? I don't see it declared anyplace and I can't think of why it should be there no matter what it is supposed to be.

  4. #4
    Registered User
    Join Date
    Mar 2003
    Posts
    32

    sorry for the lacking code tags

    I see your point, I wont forget this in the future.... will try to insert \n in at the end of the checkin records maybe this will help,

    will try to mull over the fin fout declarations outside the loops, not sure on that, but at this point I willing to try gargling peanutbutter and standing on my head, need step away and get a fresh perspective.....
    I'd like to put Murphy and his laws in headlock sometimes!

  5. #5
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    I suggest first confirming that you are reading and writing appropriately by doing something like this:

    Code:
    //open first file for input of information
    ifstream fin;
    fin.open ("G:\\HEHP\\HVMDATALOGOUT.txt", ios::in | ios::nocreate);
    if (fin.fail ())
    {
        return EXIT_FAILURE;
    }
    
    //open second file for input of information
    ifstream fin2;
    fin2.open ("G:\\HEHP\\HVMDATALOGIN.txt", ios::in | ios::nocreate);
    if (fin2.fail ())
    {
        return EXIT_FAILURE;
    }
    
    //open stream to write information to file
    ofstream fout;
    fout.open ("G:\\HEHP\\HVMDATALOGOUT2.txt", ios:ut | ios::app);
    if (fout.fail ())
    {
        cout <<"Unable to open file HVMDATALOGOUT2.txt"<<endl;
        return EXIT_FAILURE;
    }
    
    //do
    
    while (!fin.eof () && (!fin2.eof())
    {
      //input from first file
      fin >> function;
      fin >> partnerName;
      fin >> partnerId;
      fin >> equipType;
      fin >> equipNumber;
      fin >> counter;
      fin.ignore ();
      fin.getline (dateTime, 30);
      cout<< function<<endl;
      cout<< partnerName<<endl;
      cout<< partnerId<<endl;
      cout<< equipType<<endl;
      cout<< equipNumber<<endl;
      cout<< counter<<endl;
      cout<< dateTime<<endl;
      cout <<"*************************************"<<endl;
    
      //input from second file
      fin2 >> function2;
      fin2 >> partnerName2;
      fin2 >> partnerId2;
      fin2 >> equipType2;
      fin2 >> equipNumber2;
      fin2.ignore ();
      fin2.getline (dateTime2, 30);
      cout <<function2<<endl;
      cout <<partnerName2<<endl;
      cout <<partnerId2<<endl;
      cout <<equipType2<<endl;
      cout <<equipNumber2<<endl;
      cout <<dateTime2<<endl;
      cout <<"##############################"<<endl;
    
      //confirming what to write to file
      cout<<"writing to the data2 file"<<endl;
      cout <<function<<endl;
      cout <<partnerName<<endl;
      cout <<partnerId<<endl;
      cout <<equipType<<endl;
      cout <<equipNumber<<endl;
      cout <<counter<<endl;
      cout <<dateTime<<endl;
      
      //actually writing to file
      fout << function< <" "<<partnerName<< " "<< partnerId<<" "
             << equipType<<" "<<equipNumber<<" "<<counter<<"\n"
             << dateTime<< endl;
    }
    if the files being read are of the format of the file being written, then this should work fine for demonstation purposes.

    Once you have proved that the call to ignore() and getline() are working as expected, then you can work out a mechanism to do what it is you want to do. To do that I strongly recommend you be able to write it out in pseudocode with pencil and paper before you write the actual code. It usually saves a lot of time and effort to do it that way.

  6. #6
    Registered User
    Join Date
    Mar 2003
    Posts
    32

    Wink good point

    your right, I need to quit being lazy and go back to scratch, I am to frustrated with the old code not working and I have mutilated it with blind attempts to slay the problem, I appreciate your test code, I will use it for my initial testing, and as for the psued. code, thought about that and remapped my concepts last night, hope it helps.... Thnks for your efforts.... I will let you know how it works
    I'd like to put Murphy and his laws in headlock sometimes!

  7. #7
    Registered User
    Join Date
    Mar 2003
    Posts
    32

    output from test code

    elad, here are the results of the test code you suggested

    code:--------------------------------------------------------------------------------
    //open first file for input of information
    ifstream fin;
    fin.open ("G:\\HEHP\\HVMDATALOGOUT.txt", ios::in | ios::nocreate);
    if (fin.fail ())
    {
    return EXIT_FAILURE;
    }

    //open second file for input of information
    ifstream fin2;
    fin2.open ("G:\\HEHP\\HVMDATALOGIN.txt", ios::in | ios::nocreate);
    if (fin2.fail ())
    {
    return EXIT_FAILURE;
    }

    //open stream to write information to file
    ofstream fout;
    fout.open ("G:\\HEHP\\HVMDATALOGOUT2.txt", ios:ut | ios::app);
    if (fout.fail ())
    {
    cout <<"Unable to open file HVMDATALOGOUT2.txt"<<endl;
    return EXIT_FAILURE;
    }

    //do

    while (!fin.eof () && (!fin2.eof())
    {
    //input from first file
    fin >> function;
    fin >> partnerName;
    fin >> partnerId;
    fin >> equipType;
    fin >> equipNumber;
    fin >> counter;
    fin.ignore ();
    fin.getline (dateTime, 30);
    cout<< function<<endl;
    cout<< partnerName<<endl;
    cout<< partnerId<<endl;
    cout<< equipType<<endl;
    cout<< equipNumber<<endl;
    cout<< counter<<endl;
    cout<< dateTime<<endl;
    cout <<"*************************************"<<endl;

    //input from second file
    fin2 >> function2;
    fin2 >> partnerName2;
    fin2 >> partnerId2;
    fin2 >> equipType2;
    fin2 >> equipNumber2;
    fin2.ignore ();
    fin2.getline (dateTime2, 30);
    cout <<function2<<endl;
    cout <<partnerName2<<endl;
    cout <<partnerId2<<endl;
    cout <<equipType2<<endl;
    cout <<equipNumber2<<endl;
    cout <<dateTime2<<endl;
    cout <<"##############################"<<endl;

    //confirming what to write to file
    cout<<"writing to the data2 file"<<endl;
    cout <<function<<endl;
    cout <<partnerName<<endl;
    cout <<partnerId<<endl;
    cout <<equipType<<endl;
    cout <<equipNumber<<endl;
    cout <<counter<<endl;
    cout <<dateTime<<endl;

    //actually writing to file
    fout << function< <" "<<partnerName<< " "<< partnerId<<" "
    << equipType<<" "<<equipNumber<<" "<<counter<<"\n"
    << dateTime<< endl;
    }
    --------------------------------------------------------------------------------

    RESULTS:

    checkout
    Owen,Adam
    0002349439
    sgx
    922055
    0
    Tue Apr 08 11:22:17 2003
    *************************
    checkin
    Butts,William
    0002406015
    sgx
    922056
    Tue Apr 08 11:24:23 2003
    #########################
    writing to the data2 file
    checkout
    Owen,Adam
    0002349439
    sgx
    922055
    0
    Tue Apr 08 11:22:17 2003
    checkout
    Butts,William
    0002406015
    sgx
    922056
    0
    Tue Apr 08 11:22:38 2003
    *************************
    checkin
    Shaw,Jerry,W
    0001529711
    sgx
    922057
    Tue Apr 08 11:25:06 2003
    #########################
    writing to the data2 file
    checkout
    Butts,William
    0002406015
    sgx
    922056
    0
    Tue Apr 08 11:22:38 2003
    checkout
    Shaw,Jerry,W
    0001529711
    sgx
    922057
    0
    Tue Apr 08 11:23:16 2003
    *************************
    checkin
    Shaw,Jerry,W
    0001529711
    sgx
    922057

    #########################
    writing to the data2 file
    checkout
    Shaw,Jerry,W
    0001529711
    sgx
    922057
    0
    Tue Apr 08 11:23:16 2003

    notice that the second from last entry from file2 is missing the dateTime, it grabbed the same entry correctly on the first pass, but the record in question is the last record in that file, there are 4 records in file1 , and 2 file2.

    So do you think this is a getline () issue or the way I am writing to the file and establishing the end of file. It almost appears that the loop does not recognize the eof which would be the way the file is read, but file 1 does not have this problem and I write to it the same way. Is because they don't have an equal number of records?
    I'd like to put Murphy and his laws in headlock sometimes!

  8. #8
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    It's probably not getline() and it's probably not how you are writing to file. Instead, I think it is a file overread problem because when getline() finds and removes the newline char at the end of the last field in the last line of data in file2 it hasn't found or read beyond EOF yet, so it blithely loops back to the while conditional and goes through the loop one more time until it finds EOF, but then how does it stop mid loop? It can't, so it goes into undefined mode where any weird thing can happen, (often it "repeats" the last data read in correctly, but you can't count on it). This is a common problem when working with files. I used it in my "sample" only because you used it in your post and it wasn't the question you asked so I didn't want to confuse the issue.

    There are a variety of solutions to this issue depending on the way the files are structured and read. In this case, and almost as a general rule, my solution is to slightly change the sequence of read ins.

    Let's say the file sequence went:
    Smith Tues Jan 2
    Jones Wed Jan 3

    and I wanted to read the data from each line into these two variables:
    char name[21];
    char date[30];

    I would declare the appropriate stream, say fin, and then prime the stream looking for EOF, before starting the loop, and just before repeating the loop. Like this:

    Code:
    fin >> name;   //priming read for first try through loop
    while(!fin.eof())
    {
      fin.getline(date, 30);
      //do something with first full line of data, if desired
      cout << name << ' ' << date << endl;
      
       //and then try it all over again
       fin >> name;
    }
    That way when the last field of the last line is read in and I try to read the first field of the next line (which doesn't exist but the program doesn't know that yet) fin reads in EOF instead of a name and then when fin.eof() is called in the loop conditional it should equate to true and !fin.eof() should equate to false, meaning the loop should stop without the over read.

    How to structure your program otherwise will depend on what you've learned about so far. The type of program you appear to be working on would be great for using structs or classes to hold the data for each line of file input. But, if you haven't learned about structs/classes yet, then you can't do it that way.

  9. #9
    Registered User
    Join Date
    Mar 2003
    Posts
    32

    Talking got it

    I see exactly what your saying and that makes sense, that also give me a better understanding of how the files are read by the program and how they read the eof bit especially,

    as far as my education goes with this, I am teaching myself from books I buy and writing code from that, so structs and such are going to be the next section I cover, from what I can tell, they hold a better way to search through data and do comparisons.

    I love this stuff..... want to really learn to program interface apps for databases, but linking the two seems tricky, MORE READING!

    Thanks again elad, I will restructure my loops to input the next set of values and see what comes up.
    I'd like to put Murphy and his laws in headlock sometimes!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bin packing problem....
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 0
    Last Post: 08-01-2005, 05:20 AM
  2. Words and lines count problem
    By emo in forum C Programming
    Replies: 1
    Last Post: 07-12-2005, 03:36 PM
  3. getline() problem
    By mrafcho001 in forum C++ Programming
    Replies: 5
    Last Post: 06-12-2005, 01:16 AM
  4. Need help with structures
    By yoursport in forum C++ Programming
    Replies: 8
    Last Post: 04-20-2005, 11:59 AM
  5. getline help
    By ProjectsProject in forum C++ Programming
    Replies: 3
    Last Post: 06-14-2004, 11:12 AM