Last line of txt-file read twice with ifstream

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Curten
    New Member
    • Sep 2006
    • 13

    Last line of txt-file read twice with ifstream

    Hi,

    I'm using ifstream to read data from a txt-file but the last line is always read twice. How Come?

    The condition for the loop in which the file is read is

    while(!infile.e of())

    so this seems strange to me. Does anyone have a suggestion how to solve this problem?
  • gasfusion
    New Member
    • Sep 2006
    • 59

    #2
    hmm...it should work, can you post the text file?

    Comment

    • Curten
      New Member
      • Sep 2006
      • 13

      #3
      Sure, the txt-file looks like this:

      Code:
      GLU   4    3.77
         GLU  17    3.67
         GLU  13    3.84
         GLU  21    3.32
         C-   30    2.74
         HIS   5    7.42
         HIS  10    7.23
         CYS   6   99.99
         CYS   7   99.99
         CYS  11   99.99
         CYS  20   99.99
         CYS   7   99.99
         CYS  19   99.99
         TYR  14   10.07
         TYR  19    9.92
         TYR  16   10.07
         TYR  26   10.07
         N+    1    7.86
         LYS  29    9.73
         ARG  22   11.38
      I put the data in an array of structs{char[4], int, float} and everything works fine except that the last line is read (and stored) twice...

      Comment

      • r035198x
        MVP
        • Sep 2006
        • 13225

        #4
        Originally posted by Curten
        Sure, the txt-file looks like this:

        Code:
        GLU   4    3.77
           GLU  17    3.67
           GLU  13    3.84
           GLU  21    3.32
           C-   30    2.74
           HIS   5    7.42
           HIS  10    7.23
           CYS   6   99.99
           CYS   7   99.99
           CYS  11   99.99
           CYS  20   99.99
           CYS   7   99.99
           CYS  19   99.99
           TYR  14   10.07
           TYR  19    9.92
           TYR  16   10.07
           TYR  26   10.07
           N+    1    7.86
           LYS  29    9.73
           ARG  22   11.38
        I put the data in an array of structs{char[4], int, float} and everything works fine except that the last line is read (and stored) twice...
        are you not doing something with that line after the while loop?
        If not, you may need to post the whole while loop.

        Comment

        • Curten
          New Member
          • Sep 2006
          • 13

          #5
          This is the entire loop:

          Code:
                  while (!infile.eof())
                  {
                          infile>>ws;
                          if (isalpha(infile.peek())){
                                  infile>>Data.Name;
                          }
                          
                          infile>>ws;
                          if (isdigit(infile.peek())){
                                  infile>>Data.Index;
                          }
                          
                          infile>>ws;
                          if (isdigit(infile.peek()) || infile.peek() == '-'){
                                  infile>>Data.Pka;
                          }
                          DataArray.push_back(Data);                              
                   }
          Perhaps it has something to do with the way Data is inserted into the array?

          Comment

          • r035198x
            MVP
            • Sep 2006
            • 13225

            #6
            Originally posted by Curten
            This is the entire loop:

            Code:
                    while (!infile.eof())
                    {
                            infile>>ws;
                            if (isalpha(infile.peek())){
                                    infile>>Data.Name;
                            }
                            
                            infile>>ws;
                            if (isdigit(infile.peek())){
                                    infile>>Data.Index;
                            }
                            
                            infile>>ws;
                            if (isdigit(infile.peek()) || infile.peek() == '-'){
                                    infile>>Data.Pka;
                            }
                            DataArray.push_back(Data);                              
                     }
            Perhaps it has something to do with the way Data is inserted into the array?
            what makes you sure the last line is being stored twice? How did you test it?

            Comment

            • Curten
              New Member
              • Sep 2006
              • 13

              #7
              I tested it by printing the content of the array with this function:

              Code:
              void displayData (vector<proPkaData> DataArray)
              {
                      cout << "The values stored in the struct are: " << endl;
                      cout << "Name   Index   pKa  " << endl;
                      for (int i=0; i<DataArray.size(); i++){
                              cout << DataArray[i].Name << "  ";
                              cout << DataArray[i].Index << "  ";
                              cout << DataArray[i].Pka << "  " << endl;;
                      }
              }
              The call to this function in the main program is just after the loop I posted, where the DataArray is created. All the code used in this small program is now posted... =)

              Comment

              • r035198x
                MVP
                • Sep 2006
                • 13225

                #8
                This is getting worse!
                Alright, just post all of it at one go maybe someone might spot it then

                Comment

                • D_C
                  Contributor
                  • Jun 2006
                  • 293

                  #9
                  Here's my guess. You read the last data, then there is something else, like a carriage return and/or newline character before the end of file character. Then, it reads in that data, then it hits the end of file, however, it's already begun the loop. Then, since EOF causes isAlpha(), isDigit() and comparison to '-' to be false, none of the data is modified. As a result, you push the same data on twice. You could test this hypothesis by initializing the data at the beginning of each iteration of the loop.

                  First thing to do is check the test file and delete any addtional spaces at the end of it. If there isn't any extra characters, you could offset the reading like this, so it reads the next character at the end of the loop, before checking the EOF condition. Finally, you could only push the data if ws != EOF.
                  Code:
                  Read 1st Param
                  while(infile != EOF)
                  {
                    Test 1st Param
                      Update 1st Param
                  
                    Read 2nd Param
                    Test 2nd Param
                      Update 2nd Param
                  
                    Read 3rd Param
                    Test 3rd Param
                      Update 3rd Param
                  
                    Push Data;
                    Read 1st Param;
                  }

                  Comment

                  • r035198x
                    MVP
                    • Sep 2006
                    • 13225

                    #10
                    Originally posted by D_C
                    Here's my guess. You read the last data, then there is something else, like a carriage return and/or newline character before the end of file character. Then, it reads in that data, then it hits the end of file, however, it's already begun the loop. Then, since EOF causes isAlpha(), isDigit() and comparison to '-' to be false, none of the data is modified. As a result, you push the same data on twice. You could test this hypothesis by initializing the data at the beginning of each iteration of the loop.

                    First thing to do is check the test file and delete any addtional spaces at the end of it. If there isn't any extra characters, you could offset the reading like this, so it reads the next character at the end of the loop, before checking the EOF condition. Finally, you could only push the data if ws != EOF.
                    Code:
                    Read 1st Param
                    while(infile != EOF)
                    {
                      Test 1st Param
                        Update 1st Param
                    
                      Read 2nd Param
                      Test 2nd Param
                        Update 2nd Param
                    
                      Read 3rd Param
                      Test 3rd Param
                        Update 3rd Param
                    
                      Push Data;
                      Read 1st Param;
                    }
                    The only possible explanation. You could also add a test for eof that causes the method to return

                    Comment

                    • Curten
                      New Member
                      • Sep 2006
                      • 13

                      #11
                      Adding "infile>>ws ;" at the end of the loop solved the problem... =)

                      Comment

                      • Fac51
                        New Member
                        • Nov 2006
                        • 1

                        #12
                        Originally posted by Curten
                        Adding "infile>>ws ;" at the end of the loop solved the problem... =)
                        Code:
                                while (infile>>ws)
                                {
                                        if (isalpha(infile.peek())){
                                                infile>>Data.Name;
                                        }
                                        if (isdigit(infile.peek())){
                                                infile>>Data.Index;
                                        }
                                        if (isdigit(infile.peek()) || infile.peek() == '-'){
                                                infile>>Data.Pka;
                                        }
                                        DataArray.push_back(Data);                              
                                 }
                        there's a way as well....
                        though you already found a way
                        but when "while(!inFile. eof)" reads the last line twice, it's a "feature", thats what i heard
                        i think it's gay

                        Comment

                        • sfisher85
                          New Member
                          • Feb 2007
                          • 2

                          #13
                          at the end of the loop, add this line:

                          inFile.ignore(1 );


                          It should take away the rewritten line of text

                          Comment

                          Working...