Thread: C Program Help Please (File Handling)

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    27

    C Program Help Please (File Handling)

    Hello Everyone,

    I hope you are all doing well and thanks in advance for any help you can offer.

    I have the below code which need to open a .txt file with addresses in the below format, then it need to take those and sort them by zip code and output the sorted addresses to a new .txt file.

    Address Format (There is no limit to amount of addresses file can have, minimum is 2):
    FirstName, LastName
    12345 Street Name Ave.
    City Name, ST
    12345

    It needs to do this using fopen, fgets, fputs, fclose and FILE pointers but i cant get my head around this, i know its rather simple but im having trouble.

    Any help is greatly appreciated.

    here is the code that needs to be changed

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    struct storeaddress
    {
       char fandlname[50];
       char street[50];
       char cityandstate[25];
       int zip;
    };
    struct storeaddress*createaddress();
    void printaddr(int ptrct, struct storeaddress*ptr[]);
    void sortingzip(int ptrct, struct storeaddress*ptr[]);
    int main()
    {
       struct storeaddress *ptr[50];
       int ptrct = 0;
       char buf[50];
       fflush(stdin);
       do
       {
           ptr[ptrct] = createaddress();
           ptrct++;
       } while (((fgets(buf, 50, stdin) != NULL)));
       fflush(stdin);
       sortingzip(ptrct, ptr);
       printaddr(ptrct, ptr);
       return 0;
       free(ptr);
    }
    struct storeaddress*createaddress()
    {
       fflush(stdin);
       struct storeaddress *newaddress = (struct storeaddress*)malloc(sizeof(struct storeaddress));
       fgets(newaddress->fandlname, 50, stdin);
       fgets(newaddress->street, 50, stdin);
       fgets(newaddress->cityandstate, 50, stdin);
       fflush(stdin);
       scanf("%d", &newaddress->zip);
       return newaddress;
    }
    void printaddr(int ptrct, struct storeaddress *ptr[50])
    {
       int j;
       fflush(stdin);
       for (j = 0; j < ptrct; j++)
       {
           printf("\n%s%s%s%d", ptr[j]->fandlname, ptr[j]->street, ptr[j]->cityandstate, ptr[j]->zip);
       }
    };
    void sortingzip(int ptrct, struct storeaddress *ptr[])
    {
       int i, k;
       for (i = 0; i < ptrct; i++)
       {
           for (k = 0; k < ptrct; k++)
           {
               if (ptr[k]->zip > ptr[i]->zip)
               {
                   struct storeaddress *temp = ptr[i];
                   ptr[i] = ptr[k];
                   ptr[k] = temp;
               }
           }
       }
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    First of all, stop calling fflush(stdin)
    FAQ > Why fflush(stdin) is wrong - Cprogramming.com

    Next, making your zip code a string will simplify things. Mixing fgets() with scanf() leads to all sorts of difficulty for newbies (hence your ill-founded use of fflush(stdin) )

    > fgets(newaddress->cityandstate, 50, stdin);
    cityandstate is only 25 chars, so this is a potential buffer overrun.
    Always use sizeof() where you can, not magic constants.

    Eg.
    fgets(newaddress->cityandstate, sizeof(newaddress->cityandstate), stdin);
    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.

  3. #3
    Registered User
    Join Date
    Mar 2016
    Posts
    27
    Hello Salem,

    Thank you for your comments and for your help, i see what you are saying regarding my issues. I've changed them based on your comments and the program does seem to be running better.

    Do you have any ideas on how i can implement file handling in this using fopen, fgets, fputs, fclose and FILE pointers? Im really stuck there and cant figure it out.

    Any help is appreciated.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Consider that

    FILE *fp = fopen("file.txt","r");
    fgets(buff,sizeof(buff),fp);

    is very similar to
    fgets(buff,sizeof(buff),stdin);


    Also,
    printf("Hello world\n");
    is the same as
    fprintf(stdout,"Hello world\n");

    which leads nicely to
    FILE *fp = fopen("outfile.txt","w");
    fprintf(fp,"Hello world\n");
    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
    Registered User
    Join Date
    Mar 2016
    Posts
    27
    Hi Salem,

    Thanks again for your tips i really appreciate it, let me try to work and and implement this in my code to see if i can wrap my head around it and get it functioning.

    Quick question, maybe it will answer itself when i get there but how does the program know where the file is located that im trying to open? do i have to specify its location on the drive somewhere?

  6. #6
    Registered User
    Join Date
    Mar 2016
    Posts
    27
    Hello All,

    So i've revised my code quite a bit, trying to make it more efficient. I think i'm on the right track. One issue i'm having is on line 33, i'm getting an error saying too few arguments. any ideas how to fix this as i'm not sure.
    Code:
    do //reading file
        {
            fscanf(fp, "%s %s %s %d", fandlname, street, cityandstate, zip);
            ptr[ptrct] = createaddress(fandlname, street, cityandstate, zip);
            ptrct++;
        } while (((fgets(fp)) != EOF)); /*ERROR IS HERE for "FP"*/
    Here's all of my revised code. Any help, tips or pointers would be appreciated. One issue i'm wondering is how my code knows where my input.txt file is and also where to put my output.txt file. Errors have prevented me from running it successfully but i'm wondering.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    struct storeaddress
    {
        char fandlname[50];
        char street[50];
        char cityandstate[25];
        int zip;
    };
    struct storeaddress*createaddress();
    void printaddr(int ptrct, struct storeaddress*ptr[]);
    void sortingzip(int ptrct, struct storeaddress*ptr[]);
    int main()
    {
        struct storeaddress *ptr[50];
        int ptrct = 0;
        char buf[50];
        FILE *fp;
        char fandlname[50];
        char street[50];
        char cityandstate[25];
        int zip;
        fflush(stdin);
        fp = fopen("input.txt", "r");
    
    
        do //reading file
        {
            fscanf(fp, "%s %s %s %d", fandlname, street, cityandstate, zip);
            ptr[ptrct] = createaddress(fandlname, street, cityandstate, zip);
            ptrct++;
        } while (((fgets(fp)) != EOF));
        fflush(stdin);
        sortingzip(ptrct, ptr);
        printaddr(ptrct, ptr);
        return 0;
        free(ptr);
    }
    struct storeaddress*createaddress(char fandlname[50], char street[50], char cityandstate[50], int zip)
    {
        fflush(stdin);
        struct storeaddress *newaddress = (struct storeaddress*)malloc(sizeof(struct storeaddress));
        //creating struct with parametres sent while file reading
        strcpy(newaddress->fandlname, fandlname);
        strcpy(newaddress->street, street);
        strcpy(newaddress->cityandstate, cityandstate);
        newaddress->zip = zip;
        return newaddress;
    }
    void printaddr(int ptrct, struct storeaddress *ptr[50])
    {
        int j;
        fflush(stdin);
        FILE *outputFile = fopen("output.txt", "w");
        for (j = 0; j < ptrct; j++)
        {
            printf("\n%s%s%s%d", ptr[j]->fandlname, ptr[j]->street, ptr[j]->cityandstate, ptr[j]->zip);
            //writing to a file
            fprintf(outputFile, "\n%s%s%s%d", ptr[j]->fandlname, ptr[j]->street, ptr[j]->cityandstate, ptr[j]->zip);
        }
    };
    void sortingzip(int ptrct, struct storeaddress *ptr[])
    {
        int i, k;
        for (i = 0; i < ptrct; i++)
        {
            for (k = 0; k < ptrct; k++)
            {
                if (ptr[k]->zip > ptr[i]->zip)
                {
                    struct storeaddress *temp = ptr[i];
                    ptr[i] = ptr[k];
                    ptr[k] = temp;
                }
            }
        }
    }

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You normally have the while loop on the file read itself.

    Eg.
    Code:
    while ( (c=fgetc(fp)) != EOF ) {
    }
    or
    Code:
    while ( fscanf(fp, "%s %s %s %d", fandlname, street, cityandstate, zip) == 4 ) {
    }
    or
    Code:
    while ( fgets(buff,sizeof(buff),fp) != NULL ) {
    }
    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.

  8. #8
    Registered User
    Join Date
    Mar 2016
    Posts
    27
    Hello Salem,

    Thanks again for the pointer, it seems to have gotten rid of my error. I implemented a style similar to your first example. issue i'm having now is the program is crashing .

    For the Files i'm pointing to them like this, im assuming this is an error that is casued by my file not being able to be opened but still passed to fgets, here is how im opening the file:
    Code:
    fp = fopen("C:\\Desktop\input.txt","r");
    The error message i'm getting on crash is:

    "Expression: (stream != NULL)"

    I'm hitting one stop sign after the next, part of the learning process I guess right.

    Thanks again for your help.
    Last edited by rb737; 05-24-2016 at 12:24 AM.

  9. #9
    Registered User
    Join Date
    Mar 2016
    Posts
    27
    Note that the files i'm using are in my projects debug directory. I have also changed the file open process to

    Code:
    fp=fopen("input.txt","r");
    and unfortunately getting the same error.

    Any help is greatly appreciated, if the error is caused by my file not opening i guess my issue is i don't understand why its not opening.

    Ive also implemented an error checking process that is confirming that he file isnt opening but i have no idea why its not opening.
    Last edited by rb737; 05-24-2016 at 01:04 AM.

  10. #10
    Registered User
    Join Date
    Mar 2016
    Posts
    27
    Ok so i think i've fixed the issue with the files opening. i put the whole path of the file in correctly but now the program is just not working with no error messages.
    Any ideas why it might not be working now?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    struct storeaddress
    {
        char fandlname[50];
        char street[50];
        char cityandstate[50];
        int zip;
    };
    struct storeaddress*createaddress();
    void printaddr(int ptrct, struct storeaddress*ptr[]);
    void sortingzip(int ptrct, struct storeaddress*ptr[]);
    int main()
    {
        struct storeaddress *ptr[50];
        int ptrct = 0;
        char buf[50];
        FILE *fp;
        char fandlname[50];
        char street[50];
        char cityandstate[50];
        int zip;
    
    
        fp = ((fopen("c:/desktop/address.txt", "r")||((printf("Input File Open Failed \n"))&&(system("pause")))));
    
    
        while (fgets(buf, sizeof(buf), fp) != NULL) //reading file
        {
            fscanf(fp, "%s %s %s %d", fandlname, street, cityandstate, zip);
            ptr[ptrct] = createaddress(fandlname, street, cityandstate, zip);
            ptrct++;
        } 
        sortingzip(ptrct, ptr);
        printaddr(ptrct, ptr);
        return 0;
        free(ptr);
        fclose("address.txt");
        fclose("output.txt");
    }
    struct storeaddress*createaddress(char fandlname[50], char street[50], char cityandstate[50], int zip)
    {
        struct storeaddress *newaddress = (struct storeaddress*)malloc(sizeof(struct storeaddress));
        strcpy(newaddress->fandlname, fandlname);
        strcpy(newaddress->street, street);
        strcpy(newaddress->cityandstate, cityandstate);
        newaddress->zip = zip;
        return newaddress;
    }
    void printaddr(int ptrct, struct storeaddress *ptr[50])
    {
        int j;
        fflush(stdin);
        FILE *outputFile = ((fopen("c:/desktop/output.txt", "w") || ((printf("Output File Open Failed \n")) && (system("pause")))));;
        for (j = 0; j < ptrct; j++)
        {
            printf("\n%s%s%s%d", ptr[j]->fandlname, ptr[j]->street, ptr[j]->cityandstate, ptr[j]->zip);
            //writing to a file
            fprintf(outputFile, "\n%s%s%s%d", ptr[j]->fandlname, ptr[j]->street, ptr[j]->cityandstate, ptr[j]->zip);
        }
    };
    void sortingzip(int ptrct, struct storeaddress *ptr[])
    {
        int i, k;
        for (i = 0; i < ptrct; i++)
        {
            for (k = 0; k < ptrct; k++)
            {
                if (ptr[k]->zip > ptr[i]->zip)
                {
                    struct storeaddress *temp = ptr[i];
                    ptr[i] = ptr[k];
                    ptr[k] = temp;
                }
            }
        }
    }
    Last edited by rb737; 05-24-2016 at 01:18 AM.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > fp = ((fopen("c:/desktop/address.txt", "r")||((printf("Input File Open Failed \n"))&&(system("pause")))));
    You really need to stop doing complex compound expressions like this.

    Write
    Code:
    fp = (fopen("c:/desktop/address.txt", "r");
    if ( fp == NULL ) {
      perror("Input File Open Failed");
      system("pause");
      exit(1);
    }
    Use perror() to report error messages, as it will usually give you a reason as well.

    > "Expression: (stream != NULL)"
    You HAVE to make sure having opened the file that you don't then go onto use the file if the open failed.
    Otherwise, the runtime will just kill your program with an assert.

    Code:
        return 0;
        free(ptr);
        fclose("address.txt");
        fclose("output.txt");
    After the return, the free() and fclose() calls are unreachable - they never happen.

    You need to be careful in windows. Explorer by default has "hide extensions of known file types". You may have saved the file as address.txt.txt
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C file handling
    By Victor S in forum C Programming
    Replies: 3
    Last Post: 10-16-2012, 08:54 PM
  2. File Handling -Read write and edit a file
    By aprop in forum C Programming
    Replies: 3
    Last Post: 02-27-2010, 02:01 PM
  3. Help! File Handling!!!
    By sevenaces in forum C++ Programming
    Replies: 12
    Last Post: 09-28-2006, 03:32 PM
  4. C++ file handling
    By unregistered in forum C++ Programming
    Replies: 5
    Last Post: 05-29-2002, 01:33 PM

Tags for this Thread