Thread: "gas card" system, passing structures to functions(need help)

  1. #1
    Registered User
    Join Date
    Dec 2011
    Posts
    5

    "gas card" system, passing structures to functions(need help)

    Hi,
    I've been having trouble with this code; simply because the compiler either doesn't run it( a bizarre issue with the linking) or when it does, it exits immediately, without printing a single line; here it is:
    Code:
    #include<stdio.h>
    #include<string.h>
    void sort(struct c*cards,int const);
    float discharge(long const,float const);
    void charge(long const);
    struct c{
        long id;
        char plk[7];
        char name[20];
        float shm;
        float code;
    }cards[100];
    int noc;
    main(){
        int i,c;
        long id;
        float x,y,a;
        printf("Please Enter the number of cards\n");
        scanf("%d",&noc);
        printf("Please Enter the data of cards; in following order:\n");
        for(i=0;i<noc;i++)
               scanf("%7d%*1c%s%*1c%s%*1c%7.2f%*1c%3.1f",&cards[i].id,&cards[i].plk,
                    &cards[i].name,&cards[i].shm,&cards[i].code);
        for(;;c=getchar())
        {
            switch (c) {
                case 1:{
                    sort(cards,noc);
                break;
                }
                case 2:{
                    printf("Enter a card ID and a float,respectively to discharge");
                    scanf("%ld%*1c%7.2f",&id,&x);
                    a=discharge(id,x);
                    if(a==-1.00)
                        printf("your card is empty");
                    break;
                }
                case 3:{
                     printf("Enter a card ID and a float,respectively to charge the"
                             " card");
                    scanf("%ld%*1c%7.2f",&id,&y);
                    charge(id);
                       }
                case 4:{
                    for(i=0;i<noc;i++)
                    {
                        printf("ID:%ld Plate Number:%s Owner name:%s"
                        "Account Balance=%f Car Type(Code)=%f",cards[i].id,
                                cards[i].plk,cards[i].name,cards[i].shm,
                                cards[i].code);
                        return 0;
                    }
                       }
                 default :{
                        printf("INCORRECT NUMBER; ENTER AGAIN \n");
                        break;
                             }
                
            }
            }
        return 0;
    }
    void sort(struct c*array,int const k){
        int i,j;
        struct c p;
        for(i=0;i<k-1;i++)
            for(j=i+1;j<k;j++)
               if(array[i].id >array[j].id && strcmp(array[i].name,array[j].name)>0)
               {
                p=array[i];
                array[i]=array[j];
                array[j]=p;
               }    
    }
    float disccharge(long const l,float const m)
    {
        int i;
      for(i=0;i<noc;i++)  
          if(cards[i].shm< m)
              return -1.00;
          else
          {
          if(cards[i].id == l)
              cards[i].shm =cards[i].shm - m;
          return 1.00;
          }           
    }
    void charge(long const r)
    {
        int i;
        for(i=0;i<noc;i++)
            if(cards[i].id == r){
                if(cards[i].code == 1.00)
                    cards[i].shm=cards[i].shm+100.00;
                if(cards[i].code == 2.00)
                    cards[i].shm +=800.00;
            } 
    }
    my main problem I think is passing the structure "c" to the function "Sort"; I've been through references (deitel) and a thread here:
    Pass struct array to function

    Thanks in advance.
    ---
    P.S.
    what is a good source on passing structures/arrays/pointers to functions (with a lot of examples)?

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I would say you need to check your compiler settings and insure your compiler is emitting warnings, and that the warning level is as high as possible. Here are the warnings I got when I compiled your code:

    main.c|3|warning: ‘struct c’ declared inside parameter list|
    main.c|3|warning: its scope is only this definition or declaration, which is probably not what you want|
    main.c|14|error: return type defaults to ‘int’|
    main.c||In function ‘main’:|
    main.c|23|warning: format ‘%7d’ expects type ‘int *’, but argument 2 has type ‘long int *’|
    main.c|23|warning: format ‘%s’ expects type ‘char *’, but argument 3 has type ‘char (*)[7]’|
    main.c|23|warning: format ‘%s’ expects type ‘char *’, but argument 4 has type ‘char (*)[20]’|
    main.c|23|warning: unknown conversion type character ‘.’ in format|
    main.c|23|warning: unknown conversion type character ‘.’ in format|
    main.c|23|warning: too many arguments for format|
    main.c|28|error: passing argument 1 of ‘sort’ from incompatible pointer type|
    main.c|3|note: expected ‘struct c *’ but argument is of type ‘struct c *’|
    main.c|33|warning: unknown conversion type character ‘.’ in format|
    main.c|33|warning: too many arguments for format|
    main.c|35|warning: comparing floating point with == or != is unsafe|
    main.c|42|warning: unknown conversion type character ‘.’ in format|
    main.c|42|warning: too many arguments for format|
    main.c|64|error: conflicting types for ‘sort’|
    main.c|3|note: previous declaration of ‘sort’ was here|
    main.c|76|warning: no previous declaration for ‘disccharge’|
    main.c||In function ‘charge’:|
    main.c|94|warning: comparing floating point with == or != is unsafe|
    main.c|96|warning: comparing floating point with == or != is unsafe|
    main.c||In function ‘disccharge’:|
    main.c|88|warning: control reaches end of non-void function|
    ||=== Build finished: 5 errors, 17 warnings ===|
    Some of the "errors" are because you are trying to use your structure before you define the structure, move your function prototypes below the structure definition.

    It also looks like you need to study up on scanf() paying particular attention to the format specifier section.

    If you are getting warnings they should be treated as errors and fixed.

    Jim

  3. #3
    Registered User
    Join Date
    Dec 2011
    Posts
    5
    thanks;
    none of the compilers I use (cygwin for netbeans-DevC++-Visual studio 6 , even an online compiler) gave me such a long list of errors;
    could you tell me what compiler you're using? and how to alter the warning settings as you mentioned ?(as far as I know cygwin doesn't come with a graphic GUI and I'm sub-zero in Command Prompt-not an option-)

    Thanks again,

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I use gcc, and some of the compile switches I use are -Wshadow -Wmain -pedantic-errors -pedantic -Wextra -Wall -ansi -g -std=c99. You may want to look into either upgrading your Microsoft compiler to a more recent version, or trying Code::Blocks or Pelles C.

    Jim

  5. #5
    Registered User
    Join Date
    Dec 2011
    Posts
    5
    Quote Originally Posted by jimblumberg View Post
    I use gcc, and some of the compile switches I use are -Wshadow -Wmain -pedantic-errors -pedantic -Wextra -Wall -ansi -g -std=c99. You may want to look into either upgrading your Microsoft compiler to a more recent version, or trying Code::Blocks or Pelles C.

    Jim
    awesome; Thanks again Jim;
    One last look at my code:
    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    struct c{
        long id;
        char plk[7];
        char name[20];
        float shm;
        float code;
    }cards[100];
    void sort(struct c*cards,int const);
    float discharge(long const,float const);
    void charge(long const);
    int noc;
    int main(){
        int i,c;
        long id;
        float x,y,a;
        printf("Please Enter the number of cards\n");
        scanf("%d",&noc);
        printf("Please Enter the data of cards; in following order:\n");
        for(i=0;i<noc;i++)
               scanf("%ld%s%s%f%f",&cards[i].id,&cards[i].plk,&cards[i].name,&cards[i].shm,&cards[i].code);
        for(;;c=getchar())
        {
            switch (c) {
                case 1:{
                    sort(cards,noc);
                break;
                }
                case 2:{
                    printf("Enter a card ID and a float,respectively to discharge");
                    scanf("%ld%f",&id,&x);
                    a=discharge(id,x);
                    if(a==-1.00)
                        printf("your card is empty");
                    break;
                }
                case 3:{
                     printf("Enter a card ID and a float,respectively to charge the"
                             " card");
                    scanf("%ld%f",&id,&y);
                    charge(id);
                       }
                case 4:{
                    for(i=0; i<noc ; i++)
                    {
                        printf("ID:%ld Plate Number:%s Owner name:%s"
                        "Account Balance=%f Car Type(Code)=%f",cards[i].id,
                                cards[i].plk,cards[i].name,cards[i].shm,
                                cards[i].code);
                        return EXIT_SUCCESS;
                    }
                       }
                 default :{
                        printf("INCORRECT NUMBER; ENTER AGAIN \n");
                        break;
                             }
    
            }
            }
            return 0;
    }
    void sort(struct c*array,int const k){
        int i,j;
        struct c p;
        for(i=0;i<k-1;i++)
            for(j=i+1;j<k;j++)
               if(array[i].id >array[j].id && strcmp(array[i].name,array[j].name)>0)
               {
                p=array[i];
                array[i]=array[j];
                array[j]=p;
               }
    }
    float disccharge(long const l,float const m)
    {
        int i;
      for(i=0;i<noc;i++)
          if(cards[i].shm< m)
              return -1.00;
          else
          {
          if(cards[i].id == l)
              cards[i].shm =cards[i].shm - m;
          return 1.00;
          }
          return 1.00;
    }
    void charge(long const r)
    {
        int i;
        for(i=0;i<noc;i++)
            if(cards[i].id == r){
                if(cards[i].code == 1.00)
                    cards[i].shm=cards[i].shm+100.00;
                if(cards[i].code == 2.00)
                    cards[i].shm +=800.00;
            }
    }
    now , using Code.::.Blocks I get these errors:
    C:\Users\Mohammad\Desktop\assignments\2\2.c||In function 'main':|
    C:\Users\Mohammad\Desktop\assignments\2\2.c|24|war ning: format '%s' expects type 'char *', but argument 3 has type 'char (*)[7]'|
    C:\Users\Mohammad\Desktop\assignments\2\2.c|24|war ning: format '%s' expects type 'char *', but argument 4 has type 'char (*)[20]'|
    obj\Debug\2.o||In function `main':|
    C:\Users\Mohammad\Desktop\assignments\2\2.c|35|und efined reference to `discharge'|
    ||=== Build finished: 1 errors, 2 warnings ===|

    I have 3 questions and this should be done:
    1)what do I do with "format '%s' expects type 'char *', but argument 3 has type 'char (*)[7]" ?
    I defined a size for each string element of the structure. how am I supposed to fill my structure?

    2) I assigned the outcome of function discharge to a variable "a", what's the problem with that?(how to define-reference it? )

    3)the reason I used the "%*c) in my original code was to make the program skip the spaces between data entries (aside from those stupid scanf-printf confusions)..what should I do?
    -already went for this, no good came out:
    Using scanf to skip whitespace characters

    Thanks again;

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    C:\Users\Mohammad\Desktop\assignments\2\2.c|24|war ning: format '%s' expects type 'char *', but argument 3 has type 'char (*)[7]'
    This should be the line in question:
    Code:
    scanf("%ld%s%s%f%f",&cards[i].id,&cards[i].plk,&cards[i].name, &cards[i].shm,&cards[i].code);
    Look at argument 3: &cards[i].plk and how this is defined: char plk[7];
    Now lets look at some of the documentation of scanf():
    s
    Matches a sequence of bytes that are not white-space characters. The application shall ensure that the corresponding argument is a pointer to the initial byte of an array of char, signed char, or unsigned char large enough to accept the sequence and a terminating null character code, which shall be added automatically.
    Emphasis is mine. Now reading the highlighted section, how do you pass a pointer to an array to a function? Answer: When you pass an array to a function you use the name of the array without any ampersand.

    For your last error, check the spelling of the function definition, function call, and function implementation.



    Jim

  7. #7
    Registered User
    Join Date
    Dec 2011
    Posts
    5
    thanks again;
    it's starting to get a little painful now; now I get no compilation errors but the moment I enter the data it hangs and exits the program; what do you think is wrong?

    Code:
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    struct c{
        long id;
        char plk[7];
        char name[20];
        float shm;
        float code;
    }cards[100];
    void sort(struct c*cards,int const);
    float discharge(long const,float const);
    void charge(long const);
    int noc;
    int main(){
        int i,c;
        long id;
        float x,y,a;
        printf("Please Enter the number of cards\n");
        scanf("%d",&noc);
        printf("Please Enter the data of cards; in following order:\n");
        for(i=0;i<noc;i++)
               scanf("%ld%s%s%f%f",cards[i].id,cards[i].plk,cards[i].name,cards[i].shm,cards[i].code);
        for(;;c=getchar())
        {
            switch (c) {
                case 1:{
                    sort(cards,noc);
                break;
                }
                case 2:{
                    printf("Enter a card ID and a float,respectively to discharge");
                    scanf("%ld%f",&id,&x);
                    a=discharge(id,x);
                    if(a==-1.00)
                        printf("your card is empty");
                    break;
                }
                case 3:{
                     printf("Enter a card ID and a float,respectively to charge the"
                             " card");
                    scanf("%ld%f",&id,&y);
                    charge(id);
                       }
                case 4:{
                    for(i=0; i<noc ; i++)
                    {
                        printf("ID:%ld Plate Number:%s Owner name:%s"
                        "Account Balance=%f Car Type(Code)=%f",cards[i].id,
                                cards[i].plk,cards[i].name,cards[i].shm,
                                cards[i].code);
                        return EXIT_SUCCESS;
                    }
                       }
                 default :{
                        printf("INCORRECT NUMBER; ENTER AGAIN \n");
                        break;
                             }
    
            }
            }
            return 0;
    }
    void sort(struct c*array,int const k){
        int i,j;
        struct c p;
        for(i=0;i<k-1;i++)
            for(j=i+1;j<k;j++)
               if(array[i].id >array[j].id && strcmp(array[i].name,array[j].name)>0)
               {
                p=array[i];
                array[i]=array[j];
                array[j]=p;
               }
    }
    float discharge(long const l,float const m)
    {
        int i;
      for(i=0;i<noc;i++)
          if(cards[i].shm< m)
              return -1.00;
          else
          {
          if(cards[i].id == l)
              cards[i].shm =cards[i].shm - m;
          return 1.00;
          }
          return 1.00;
    }
    void charge(long const r)
    {
        int i;
        for(i=0;i<noc;i++)
            if(cards[i].id == r){
                if(cards[i].code == 1.00)
                    cards[i].shm=cards[i].shm+100.00;
                if(cards[i].code == 2.00)
                    cards[i].shm +=800.00;
            }
    }

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I still get the following warnings:
    main.c||In function ‘main’:|
    main.c|23|warning: format ‘%ld’ expects type ‘long int *’, but argument 2 has type ‘long int’|
    main.c|23|warning: format ‘%f’ expects type ‘float *’, but argument 5 has type ‘double’|
    main.c|23|warning: format ‘%f’ expects type ‘float *’, but argument 6 has type ‘double’|
    main.c|35|warning: comparing floating point with == or != is unsafe|
    main.c||In function ‘charge’:|
    main.c|95|warning: comparing floating point with == or != is unsafe|
    main.c|97|warning: comparing floating point with == or != is unsafe|
    ||=== Build finished: 0 errors, 6 warnings ===|
    Line 23 is:
    Code:
               scanf("%ld%s%s%f%f",cards[i].id,cards[i].plk,cards[i].name,cards[i].shm,cards[i].code);
    You really need to read up on the scanf() function. You must pass this function pointers to your variables. So for everything but a C-string you need to add an ampersand. Also the format specifier for a double is not "%f" this is for a float, you need to use the correct specifier for a double.

    Jim

  9. #9
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    You need to pass addresses to scanf. Strings are already addresses, but your ints and floats need an ampersand before them.

    You're missing a break on case 3.

    The return EXIT_SUCCESS in case 4 is wacky.

    And your loop control is out to lunch. Try a do/while loop with the c=getchar() just after the do.

    I haven't looked at your other functions, but noc shouldn't be global. Define it in main and pass it as a parameter.

  10. #10
    Registered User
    Join Date
    Dec 2011
    Posts
    5
    Hello again and thanks for your useful advice;
    now I got really frustrated and thought what the heck , I'm gonna write it from ground up. so I wrote this which is essentially the same thing; anyway it's now running and there's no specific problem in the main while(1) loop but when I enter the "2" operator and add some gas to an account I get a "access violation" error, which I don't understand. what seems to be the problem?

    Code:
    #include<stdio.h>
    #include<string.h>
    
    #define MAX 100
    #define TRUE 1
    #define LINEPPAGE 25
    
    struct data{ long ID;
    char PLK[8];
    char name[21];
    double shm;
    int code;
    }cards[MAX];
    static int noc;
    
    int sort()
    {
        int i,j;
        struct data temp;
        for(i=0;i<noc-1;i++)
        {
        for(j=i+1;j<noc;j++)
        {
        if((cards[i].ID>cards[j].ID) && strcmp(cards[i].name,cards[j].name)<0)
            {
                temp=cards[i];
                cards[i]=cards[j];
                cards[j]=temp;
            }
        }
        }
       return 0;
    }
    int charge()
    {
        int i;
        for (i=0;i<noc;i++)
        {
            if(cards[i].code==1)
            {
            cards[i].shm+=100;
            }
            else
            cards[i].shm+=800;
        }
        return 0;
    }
    
    int main()
    {
        long id_search;
        double shm_discharge=0,rem;
        int i,c,found=0;
        puts("Enter the number of cards:\n");
        scanf("%d",&noc);
        printf("%s%s", "Please Enter the data of cards; in following order\n", "ID(7char) Plate Number(Max of 7 Char) Name(Max of 20 Char)\nAccount Balance(XX.YY) Car Type Code(1 or 2):\n");
        for(i=0;i<noc;i++)
        {
            scanf("%ld%s%s%lf%d",&cards[i].ID,cards[i].PLK,cards[i].name,&cards[i].shm,&cards[i].code);
    
        }
        c=getchar();
        puts("enter an operator 1,2,3 or 4");
        c=getchar();
        while(1)
        {
    
    
            switch (c){
    
            case '1':
                {
                c=getchar();
            sort();
            break;
                }
            case '2':
                {
            puts("Enter the number of card");
            c=getchar();
            scanf("%ld",&id_search);
            c=getchar();
            for(i=0;i<noc;i++)
            {
                    if (id_search==cards[i].ID){
                        printf("Enter the amount of gas \n");
                        scanf("%lf",shm_discharge);
                        c=getchar();
                        cards[i].shm-=shm_discharge;
                        found=TRUE;
                        printf("Operation done. account balance is now %lf",&rem);
                        break;
                      }
                    else
                    {
                    continue;
                    }
            }
            if(found!=TRUE){
            puts("card number not found");
            break;
            }
            found = 0;
            break;
                }
            case '3':
                {
                    c=getchar();
            charge();
            break;
                }
            case '4':
                {
                    c=getchar();
            for(i=0;i<noc;i++)
            {
                if(!(i%LINEPPAGE)){
                printf("                          NATIONAL PETROL CONSUMPTION MANAGMENT REPORT");
                printf("CARD ID       CAR PLATE       OWNER NAME                 BALANCE     CAR TYPE");
                printf("------------------------------------------------------------------------------");
                }
                printf("%10ld%10s%25s%7.2lf%3.1lf",cards[i].ID,cards[i].PLK,cards[i].name,cards[i].shm,cards[i].code);
            }
            return 0;
                }
            default:
                {
            printf("INCORRECT NUMBER, TRY AGAIN.\n");
            c=getchar();
            break;
                }
    
            }
            c=getchar();
        }
        return 0;
    }
    here's the error VS 2010 gives me:
    Unhandled exception at 0x1032f508 (msvcr100d.dll) in l.exe: 0xC0000005: Access violation writing location 0x00000000.
    Thanks in advance

  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
    You're still messing up on printf/scanf.
    Code:
    $ gcc -Wall -Wextra bar.c
    bar.c: In function ‘main’:
    bar.c:87: warning: format ‘%lf’ expects type ‘double *’, but argument 2 has type ‘double’
    bar.c:91: warning: format ‘%lf’ expects type ‘double’, but argument 2 has type ‘double *’
    bar.c:122: warning: format ‘%3.1lf’ expects type ‘double’, but argument 6 has type ‘int’
    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.

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    You need to check your compiler settings and insure that warnings are being emitted, and that the highest setting is selected. Next you need to study carefully the documentation for printf() and scanf(). You may also want to review Pointers and maybe Passing arguments.

    Jim

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Use system("file location") to open root folder?
    By muffinman8641 in forum C++ Programming
    Replies: 9
    Last Post: 03-17-2011, 10:45 AM
  2. Replies: 18
    Last Post: 05-26-2008, 11:23 PM
  3. passing strings from functions as the "return" part
    By fraktal in forum C Programming
    Replies: 8
    Last Post: 12-13-2005, 01:38 AM
  4. "itoa"-"_itoa" , "inp"-"_inp", Why some functions have "
    By L.O.K. in forum Windows Programming
    Replies: 5
    Last Post: 12-08-2002, 08:25 AM
  5. "CWnd"-"HWnd","CBitmap"-"HBitmap"...., What is mean by "
    By L.O.K. in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 07:59 AM