Thread: Skipping the line.

  1. #1
    Registered User
    Join Date
    Nov 2005
    Posts
    19

    Question Skipping the line.

    I really hate to ask this, but I just can't stand this program any more. I have been working on it about 4-8 hours a day for last two or three days. And haven't made much progress. I am about to rip my hair out T-T But enough of that.

    I want it to work like an address book, but get data from a file. When the program sees blank line, it should move on. But this function seems to be moving a line or two early. There are 4 lines (5 including the name that is copied into the function first). The loop will quit when it gets to the last line of the current company info, but the blank line gets put into the next companies name, and it shifts back from there. I tried adding an extra 'fgets' after the loop ended, but it didn't work. It seems to stop after picking up 4 lines, whether there are 5 lines or 4 in the company details.

    I'll be back in a few. I am going to bash my head again a wall for a few minutes. Thanks in advance!

    This is the function :

    Code:
    # include "lab05.h"
    
    FILE *addLoop( struct entry **current, FILE ***fp, char name[]){
    
        char buffer[ MAX ];
        char buffer2[ MAX ];
        char *str;
        char *str2;
        int i;
    
        strcpy( (*current)->name, name );
        i = 0;
    
        while ( i<=4 && str!=NULL && !feof(**fp) ){
    
            fgets( name, MAX, **fp );
            strcpy( buffer, name);
            strcpy( buffer2, buffer);
            str = strtok( buffer, REMOVE);
            str2 = strtok( buffer2, "\n");
            if( str2!=NULL )
            strcpy ((*current)->line[i], str2);
    
            i++;
        }
    
        (*current)->left = NULL;
        (*current)->right = NULL;
    
        if ( i > 6 ){
          printf("\nError FFFE : Data file is corrupt. Exiting...\n");
          fputs( "Error FFFE : Data file is corrupt. Exiting...", stderr);
          exit(0);
        }
        return **fp;
    }

  2. #2
    Registered User
    Join Date
    Nov 2005
    Posts
    19
    Btw, I can send you a copy of my entire program zipped and with the make file if you need.

  3. #3
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    first of all there are error in your code

    Code:
    FILE *addLoop( struct entry **current, FILE *fp, char name[])
    as u are returning a file pointer back u dont need point to point refernce. cos u'r are returning back pointer position

    Code:
    while ( i<=4 && str!=NULL && !feof(**fp) ){
    
            fgets( name, MAX, **fp );
            strcpy( buffer, name);
            strcpy( buffer2, buffer);
            str = strtok( buffer, REMOVE);
            str2 = strtok( buffer2, "\n");
            if( str2!=NULL )
            strcpy ((*current)->line[i], str2);
    
            i++;
        }
    fgets function returns a EOF file at soon it reaches the end.

    Code:
    while(fgets(str, 100, fp) != EOF)
    {
    ...
    ...
    }
    which solved the problem of fgets()

    it would be better to open and close the file in the function rather than sending the file pointer to the fucntion and returning it

    ssharish2005

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > FILE ***fp
    This many levels of indirection seems completely unnecessary.
    I'd suspect you're not even calling it properly.

    Without some supporting declarations, it's hard to say what is going on.

    If you're building a linked list or a tree, then I strongly suggest you separate the "read the file" from the "add to data structure" code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    1. Why do you need FILE*** instead of FILE*?
    2. str is not initialized before first use
    3. you overwriting incoming string name, is it what you want to do?
    4. feof should be checked after you tried to read from file before you actually using the data read

    5. if ( i > 6 ) this cannot be achieved due to while ( i<=4 - loop exits when i==5
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Registered User
    Join Date
    Nov 2005
    Posts
    19
    How would I do something like that :S ? Like have a function write to 2D arrary from the file, then send the 2D array to a function that adds the lines to the tree?

  7. #7
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    so write two function which does the follwing job

    1. get the data from the file and place that in 2D array
    2. send the 2D array to one ore function which addes that data from the "D to tree

    hint: Function prototype

    Code:
    FILE * Getdata(char *filename); <--- to get datat from file
    
    void AddToTree(struct node **root, char **data);
    ssharish2005

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Maybe start by posting some examples of the lines you read from the file, and the data structures you're working with.

    Code:
    while ( fgets( buff, sizeof buff, fp ) != NULL ) {
      // validate and extract data
      // if valid, add to data structure.
    }
    You can test the add to data structure with known good data without ever going anywhere near a file. When you know it works, then you add the file reading code, knowing that half the battle is already won.

    Trying to do the whole thing at once at least quadruples the effort IMO.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Nov 2005
    Posts
    19
    Hmmmm, well I might as well give it a shot! Thanks!

  10. #10
    Registered User
    Join Date
    Nov 2005
    Posts
    19
    How about this? Or should I do it all in main? (Im trying to make functions that I can use later, but I guess I am not doing that to well ^ ^; )

    Code:
    #include "lab05.h"
    
    int buildTree ( struct head *soil, FILE *fp, char companyList [][WORD],
                    int *amount ){
    
        char buffer [ MAX ];
        char check [ MAX ];
        char *tempS1;
        int i;
        struct entry *current;
    
       // Create a new root if root is NULL
        if ( soil -> root == NULL ){
            soil -> root = (struct entry *) malloc (sizeof(struct entry));
            soil -> root -> left = NULL;
            soil -> root -> right = NULL;
           // Null name string
            strcpy (soil -> root -> name, "");
           // Null line strings
            for (i=0; i<5; i++)
                strcpy(soil -> root -> line[i], "");
        }
    
        current = soil -> root;
    
       // Run while loop till script/data file reaches EOF
        while ( fgets( buffer, MAX, fp) != EOF ){
    
           // Place tokenized string in tempS1 to check for blank lines
            strcpy ( check, buffer );
            tempS1 = strtok ( check, REMOVE );
    
           // If line isn't blank, add entry to tree
            if ( tempS1 != NULL ){
             // Put company name into company list
              strcpy (companyList[*amount], buffer);
              fp = getData ( dataList, fp);
              addData (dataList, soil )
              *amount ++;
            }
    
        }
    
    return 0;
    
    }

  11. #11
    Registered User
    Join Date
    Nov 2005
    Posts
    19
    I am really starting to freak out...

    What am I doing wrong. I'll be back, need to take a walk. This is the thrid time I have rebuilt my adding to tree functions

    Code:
    ///////////////////////////////////////////////////////////////////////
    // Program      : Lab05
    // Function     : getData
    // File         : getData.c
    // Description  : Extract upto x lines of data from file
    //              :  quit when a blank line is found
    // Variable Ref : dataList - list of company info
    //              : fp - File pointer
    //              : linesR - Number of lines returned
    //              : buffer - temporary line storage
    //              : buffer2 - temporary line storage
    //              : str - tokenized line storage
    //              : str2 - tokenized line storage
    //////////////////////////////////////////////////////////
    
    #include "lab05.h"
    
    FILE *getData ( char *dataList[5], FILE *fp, int *linesR){
    
        int i;
        char buffer [MAX];
        char buffer2 [MAX];
        char *str;
        char *str2;
    
        i = 0;
    
        while ( (fgets ( buffer, MAX-1, fp ) != EOF) ){
    
           // Exit Prgm if 'i' is five, as there can only be
            // 5 or less lines in the company data (0, 1, 2, 3, & 4)
            if ( i == 5 ){
                printf("\nError FFFE : Data file setup incorrectly. Exiting");
                fputs("Error FFFE : Data file setup incorrectly. Exiting", stderr);
                exit(0);
            }
    
            strcpy ( buffer2, buffer );
    
           // Used to see if line is blank
            str = strtok ( buffer, REMOVE );
    
           // Take out the new line character
            str2 = strtok ( buffer2, "\n" );
    
           //
            if ( str == NULL ){
                return fp;
                *linesR = i;
            }
    
           // Add str2 to 'dataList'
            strcpy ( dataList[i] , str2);
    printf("\ngetData 1.0 : dataList[%d] : <%s>", i, dataList[i]);
    
    
           // Add one to i
            i++;
        }
    
        *linesR = i;
    
        return fp;
    }
    Code:
    (c1400a01@pstcc11) #:~/1400/Lab05> make
    gcc -Wall -c main.c
    gcc -Wall -c promptFile.c
    gcc -Wall -c fileOpen.c
    gcc -Wall -c buildTree.c
    buildTree.c: In function `buildTree':
    buildTree.c:52: warning: comparison between pointer and integer
    buildTree.c:62: warning: passing arg 1 of `getData' from incompatible pointer type
    buildTree.c:64: warning: value computed is not used
    gcc -Wall -c skipEntry.c
    gcc -Wall -c upperAll.c
    gcc -Wall -c displayTree.c
    gcc -Wall -c getData.c
    getData.c:18: conflicting types for `getData'
    lab05.h:40: previous declaration of `getData'
    getData.c: In function `getData':
    getData.c:28: warning: comparison between pointer and integer

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well if you can't even use fgets properly, what hope is there?

    It should be
    while ( fgets ( buffer, sizeof buffer, fp ) !=NULL )
    1. It returns NULL, not EOF on error or end of file
    2. There is no need to do -1 to allow for the \0

    Then fix your warnings.
    For a start, make the prototype in you header file match the declaration in your code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Nov 2005
    Posts
    19
    I got that fixed, the walked help to say the least. Thanks btw

    (Yeah the fgets I looked up and it said it returned NULL. Though ssharish2005 said to use != EOF so thats half the reason I used it. ^ ^; Sorry)

    I'll bug you guys some more if I need too

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. adding line numbers and concatenating a filename
    By durrty in forum C Programming
    Replies: 25
    Last Post: 06-28-2008, 03:36 AM
  2. Reading a buffer line by line, while using system read
    By Hammad Saleem in forum C Programming
    Replies: 9
    Last Post: 05-27-2008, 05:41 AM
  3. line number on a rich edit control
    By rakan in forum Windows Programming
    Replies: 1
    Last Post: 02-18-2008, 07:58 AM
  4. Adding Line numbers in Word
    By Mister C in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 06-24-2004, 08:45 PM
  5. Trouble replacing line of file
    By Rpog in forum C Programming
    Replies: 4
    Last Post: 04-19-2004, 10:22 AM