#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    245
    Rep Power
    12

    The last line was printed twice


    The last line is printed twice ( post #3)

    I ran the new code but the last line is printed twice.

    ===========================
    root:~# ./getdata3

    # Samba SMB password file
    public:501:85DBEE24101CEFF8AAD3B435B51404EEB51013B2730E1F16DF6DB7C3A73AD60:[U ]:LCT-3AB622A2:
    user_name[] = public
    admin:501:2B251B4003C6F043CA53DE06F7962527:C2D7C320A09B649A91AEC96D4CC32662:[UX ]:LCT-3E21AEC3:
    user_name[] = admin

    The last line below was printed twice

    admin:501:2B251B4003C6F043CA53DE06F7962527:C2D7C320A09B649A91AEC96D4CC32662:[UX ]:LCT-3E21AEC3:
    user_name[] = admin


    ===========================


    int main(void)
    {
    FILE *in;
    char buffer[255];
    char user_name[32];
    int n;
    int i = 0;

    if((in = fopen("/etc/samba/smbpasswd","r")) == NULL)
    {
    perror("Couldn't open file");
    return 1;
    }

    while(!feof(in))

    {
    fgets(buffer, 255, in);
    n = strlen(buffer) - 1;

    if(n == 0)
    printf("nothing read from file\n");
    else
    {
    if(buffer[n] == '\n')
    buffer[n] = '\0';
    printf("%s\n", buffer);
    }


    for (i = 0; i <= 254; i++)
    if (buffer[i] != ':')
    user_name [i] = buffer[i];
    else
    {
    user_name [i] = '\0';
    printf ("user_name[] = %s\n", user_name);
    break;
    }
    }

    fclose(in);
    return 0;
    }
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Handling end-of-file can always be a bit tricky. Basically, when you read zero bytes, then you've hit the end of the file. And until you make that failed attempt, the EOF status hasn't been set.

    So you hit the end of the file, but you went on to output the "new line of data", which was just the old line unchanged. That's why the last line appears twice.

    When you read zero bytes, either exit out of the loop (eg, with a break) or find some way to only print something out if you read new data.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    245
    Rep Power
    12

    How would zero byte be tested ?


    If I test for zero byte, then how would the above code to be stested ?

    while (!(eof) or file_pointer == "")
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    I would tend towards something like this:
    Code:
    do
    {
        fgets(buffer, 255, in); 
        n = strlen(buffer) - 1; 
        if (n != 0)
        {
            /* do your processing here */
        }
    } while(!feof(in)); 
    
    fclose(in);
    The idea is that you only process the input data if the read was successful.

    BTW, another way to test for fgets failing (including for an EOF condition) would be if it returns a NULL.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    245
    Rep Power
    12

    Smile I did as you have suggested, but it still print


    I did as you have suggested, but it still print the last line twice.

    root:~# ./getdata4
    # Samba SMB password file
    public:501:85DBEE24101CEFF8AAD3B435B51404EE:DB51013B2730E1F16DF6DB7C3A73AD60:[U ]:LCT-3AB622A2:
    j = 0
    user_name[] = public

    admin:501:2B251B4003C6F043CA53DE06F7962527:C2D7C320A09B649A91AEC96D4CC32662:[UX ]:LCT-3E21AEC3:
    j = 1
    user_name[] = admin

    linh:1016:2B251B4003C6F043661B0422047CD33E:204093D0472B84F9671E87EDDF78B872:[UX ]:LCT-3F07F8F9:
    j = 2
    user_name[] = linh

    ------------ The last line is printed twice ------------------

    linh:1016:2B251B4003C6F043661B0422047CD33E:204093D0472B84F9671E87EDDF78B872:[UX ]:LCT-3F07F8F9:
    j = 3
    user_name[] = linh

    ======================================
    Code:
    #include <stdio.h>
    
    int main(void)
    {
      FILE *in;
      char buffer[255];
      char user_name[32];
      int n;
      int i = 0;
      int j = 0;
    
      if((in = fopen("/etc/samba/smbpasswd","r")) == NULL)
       {
         perror("Couldn't open file");
         return 1;
       }
    
      do
        {
          fgets(buffer, 255, in);
          n = strlen(buffer) - 1;
          if (n != 0)
            {
              if(buffer[n] == '\n')
                buffer[n] = '\0';
              printf("%s\n", buffer);
    
              for (i = 0; i <= 254; i++)
                if (buffer[i] != ':')
                  user_name [i] = buffer[i];
                else
                  {
                    user_name [i] = '\0';
                    printf ("j = %d\n", j);
                    printf ("user_name[] = %s\n", user_name);
                    printf ("\n");
                    j++;
                    break;
                  }
            }
          else printf("nothing read from file\n");
        }
      while(!feof(in));
    
      fclose(in);
      return 0;
    }
    Last edited by linh; July 23rd, 2003 at 09:25 AM.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2002
    Posts
    272
    Rep Power
    18
    Try adding the following line as the first line of your do loop.

    buffer[0] = '\0';

    I suspect that fgets doesn't change the buffer if it doesn't read anything in. That means that the string from the last read is still there and you will print it out.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2003
    Posts
    245
    Rep Power
    12

    Thumbs up It worked !


    Thank you dwise1_aol and 3dfxMM for answering my questions.

IMN logo majestic logo threadwatch logo seochat tools logo