Thread: 'const int' vs. #define and ouput issues

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    11

    'const int' vs. #define and ouput issues

    Code:
    /*******************************************************        
     * Purpose:  Design an airline reservation structure that contains the following data:
     *  
     * Flight Number
     * Originating Airport Code (3 characters)
     * Destination Airport Code (3 characters)
     * Starting time
     * Arrival time
    ***************************************************************/
    #include <stdio.h>
    
    struct itinerary
    {
        int flight;                         /* Flight number                */
        char origin_airport[3];             /* Airport of origin            */
        char dest_airport[3];               /* Destination airport          */
        int start_time;                     /* Time of start of flight      */
        int arrival_time;                   /* Time of arrival              */
    };
    
    #define MAX_ENTRIES 50                  /* Max number of stucts to create       */
    struct itinerary list[MAX_ENTRIES];     /* Array of structures for data         */
    void print_itinerary(int counter);      /* Prototype for printing out info      */
    
    
    int main()
    {
        char line[10];                      /* Input from the user                  */
        int counter = 0;                    /* Counter for loop starts at zero      */
     char quit;                          /* Variable used to exit loop           */
    
        while(counter <= MAX_ENTRIES)
        {
    
            printf("Enter the flight number: ");
            fgets(line, sizeof(line), stdin);
            sscanf(line, "%d", &list[counter].flight);
    
            printf("Enter the airport origin: ");
            fgets(line, sizeof(line), stdin);
            sscanf(line, "%s", &list[counter].origin_airport);
    
            printf("Enter the destination airport: ");
            fgets(line, sizeof(line), stdin);
            sscanf(line, "%s", &list[counter].dest_airport);
    
            printf("Enter the start time: ");
            fgets(line, sizeof(line), stdin);
            sscanf(line, "%d", &list[counter].start_time);
    
            printf("Enter the arrival time: ");
            fgets(line, sizeof(line), stdin);
            sscanf(line, "%d", &list[counter].arrival_time);
    
            printf("Do you wish to enter another flight? (<enter>=yes or n=no) ");
            fgets(line, sizeof(line), stdin);
            sscanf(line, "%c", &quit);
            if(quit == 'n')
                break;
    
            ++counter;
    
        }
    
        print_itinerary(counter);
    
        return(0);
    }
    
    void print_itinerary(int counter)
    {
        int index = 0;              /* Index to cycle through the program   */
    
        while(index <= counter)
        {
            printf("Flight:             %d \n", list[index].flight);
            printf("Origin Airport:     %s \n", list[index].origin_airport);
            printf("Desination Airport  %s \n", list[index].dest_airport);
            printf("Start:              %d \n", list[index].start_time);
            printf("Arrive:             %d \n", list[index].arrival_time);
            printf("\n");
    
            ++index;
        }
    
        return;
    }
    Two questions:

    1) Why do I have to use '#define' instead of 'const int' I get an error message with 'const int':

    error: variable-size type declared outside of any function 'const int'

    $gcc --version

    gcc (GCC) 3.4.2 [FreeBSD] 20040728

    2) The print to screen output I get is:

    Enter the flight number: 110
    Enter the airport origin: TLH
    Enter the destination airport: SEA
    Enter the start time: 1110
    Enter the arrival time: 1230
    Do you wish to enter another flight? (<enter>=yes or n=no) n
    Flight: 110
    Origin Airport: TLHSEA
    Desination Airport SEA
    Start: 1110
    Arrive: 1230

    As you can see I get TLH and SEA put together in the ouput to screen. This may be obvious to you guys.

    Thanks in advance for any and all help.

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
        char origin_airport[3];             /* Airport of origin            */
        char dest_airport[3];               /* Destination airport          */
    In memory, "SEA" looks like 'S', 'E', 'A', '\0'. That's 4 chars because of the null-terminating zero, and you're only reserving room for 3 chars. Changing the arrays to be size 4 should fix the problem.

    As far as the 'const int' problem, I'm not sure off the top of my head. Also, I would change all of your sscanf(..., "%s", ...);'s to sscanf(..., "%3s", ...); to avoid buffer overflow possibilities.
    Last edited by itsme86; 12-30-2004 at 01:23 PM.
    If you understand what you're doing, you're not learning anything.

  3. #3
    Registered User
    Join Date
    Dec 2004
    Posts
    11
    That was the source of my problem for the output to the screen. I always forget the end of line character. Maybe this will cause me to pay more attention in the future.

    Thanks

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    An array in C requires a constant value. When you declare a variable as const it is not a constant, but rather a variable who's value cannot change (the distiction may be hard for humans to make, but it's very valid for C compilers). A constant expression is one which can be evaluated without looking up the value of a variable.

    When you declare something as:
    Code:
    #define MAX_ENTRIES 50
    The preprocessor replaced all instances of MAX_ENTRIES that it finds with the value 50. So when the compiler parses the code, it sees the value '50', and not any sort of variable.

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by bithub
    An array in C requires a constant value.
    Not in C99 it doesn't. So if you want an array you can have somewhat dynamic, you must be sure to be compiling as C99.

    But personally, I like the old method. I don't see the need for them myself.

    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    His code wont compile as C99 either since the array is global. Variable length arrays must be within block scope, or function prototype scope.

  7. #7
    Quote Originally Posted by silverback011
    Two questions:

    1) Why do I have to use '#define' instead of 'const int' I get an error message with 'const int':

    error: variable-size type declared outside of any function 'const int'

    $gcc --version

    gcc (GCC) 3.4.2 [FreeBSD] 20040728
    VLA only works inside a block.

    You code is buggy (buffer overflow etc.)
    Try this. Ask for details if necessary
    Code:
    /*******************************************************
     * Purpose:  Design an airline reservation structure that contains the
     *           following data:
     *
     * Flight Number
     * Originating Airport Code (3 characters)
     * Destination Airport Code (3 characters)
     * Starting time
     * Arrival time
    ***************************************************************/
    #include <stdio.h>
    #include <string.h>
    
    struct itinerary
    {
       int flight;                  /* Flight number                */
       char origin_airport[4];      /* Airport of origin            */
       char dest_airport[4];        /* Destination airport          */
       int start_time;              /* Time of start of flight      */
       int arrival_time;            /* Time of arrival              */
    };
    
    static void print_itinerary (struct itinerary const *list, size_t counter)
    {
       size_t i;                    /* Index to cycle through the program   */
    
       for (i = 0; i < counter; i++)
       {
          struct itinerary const *p = list + i;
    
          printf ("Flight:             %d \n", p->flight);
          printf ("Origin Airport:     %s \n", p->origin_airport);
          printf ("Desination Airport  %s \n", p->dest_airport);
          printf ("Start:              %d \n", p->start_time);
          printf ("Arrive:             %d \n", p->arrival_time);
          printf ("\n");
       }
    
       return;
    }
    
    static int get_itinerary (struct itinerary *list, int nb)
    {
       char line[10];               /* Input from the user                  */
       int counter = 0;             /* Counter for loop starts at zero      */
    
       while (counter < nb)
       {
          struct itinerary *p = list + counter;
    
          printf ("Enter the flight number: ");
          fgets (line, sizeof line, stdin);
          sscanf (line, "%d", &p->flight);
    
          printf ("Enter the airport origin: ");
          fgets (line, sizeof line, stdin);
          *p->origin_airport = 0;
          strncat (p->origin_airport, line, sizeof p->origin_airport - 1);
    
          printf ("Enter the destination airport: ");
          fgets (line, sizeof line, stdin);
          *p->dest_airport = 0;
          strncat (p->dest_airport, line, sizeof p->dest_airport - 1);
    
          printf ("Enter the start time: ");
          fgets (line, sizeof line, stdin);
          sscanf (line, "%d", &p->start_time);
    
          printf ("Enter the arrival time: ");
          fgets (line, sizeof line, stdin);
          sscanf (line, "%d", &p->arrival_time);
    
          printf ("Do you wish to enter another flight? (<enter>=yes or n=no) ");
          fgets (line, sizeof line, stdin);
          {
             char quit;             /* Variable used to exit loop           */
             sscanf (line, "%c", &quit);
             if (quit == 'n')
                break;
          }
          ++counter;
       }
       return counter;
    }
    
    int main ()
    {
       enum
       {
          MAX_ENTRIES = 50
       };                           /* Max number of stucts to create       */
       struct itinerary list[MAX_ENTRIES];  /* Array of structures for data         */
    
       int counter = get_itinerary (list, MAX_ENTRIES);
    
       print_itinerary (list, counter);
       (void) getchar ();
       return 0;
    }
    Works fine now:
    Code:
    Enter the flight number      : 110
    Enter the airport origin     : TLH
    Enter the destination airport: SEA
    Enter the start time         : 1110
    Enter the arrival time       : 1230
    Do you wish to enter another flight? (<enter>=yes or n=no) n
    Flight:             110
    Origin Airport:     TLH
    Desination Airport  SEA
    Start:              1110
    Arrive:             1230
    Emmanuel Delahaye

    "C is a sharp tool"

  8. #8
    Quote Originally Posted by quzah
    <about C99 VLA>
    But personally, I like the old method. I don't see the need for them myself.
    Agreed.
    Emmanuel Delahaye

    "C is a sharp tool"

  9. #9
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I didn't get any output because get_itinerary returned 0 running through your example. Shouldn't the counter be incremented before the break? And wouldn't it be better to consistently use size_t for the counter?
    Code:
    static void print_itinerary (struct itinerary const *list, size_t counter)
    {
       size_t i;                    /* Index to cycle through the program   */
    
       for (i = 0; i < counter; i++)
       /* ... */
    }
    
    static int get_itinerary (struct itinerary *list, int nb)
    {
       int counter = 0;             /* Counter for loop starts at zero      */
       /* ... */
       while (counter < nb)
       {
          /* ... */
          {
             char quit;             /* Variable used to exit loop           */
             sscanf (line, "%c", &quit);
             if (quit == 'n')
                break;
          }
          ++counter;
       }
       return counter;
    }
    
    int main ()
    {
       enum
       {
          MAX_ENTRIES = 50
       };                           /* Max number of stucts to create       */
       struct itinerary list[MAX_ENTRIES];  /* Array of structures for data         */
    
       int counter = get_itinerary (list, MAX_ENTRIES);
    
       print_itinerary (list, counter);
       (void) getchar ();
       return 0;
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  10. #10
    Quote Originally Posted by Dave_Sinkula
    I didn't get any output because get_itinerary returned 0 running through your example. Shouldn't the counter be incremented before the break?
    Correct. It was a last minute change on the IDE that I forgot to report on my editor from wher I do the copy and paste.
    And wouldn't it be better to consistently use size_t for the counter?
    Agreed.

    Last version:
    Code:
    /*******************************************************
     * Purpose:  Design an airline reservation structure that contains the
     *           following data:
     *
     * Flight Number
     * Originating Airport Code (3 characters)
     * Destination Airport Code (3 characters)
     * Starting time
     * Arrival time
    ***************************************************************/
    #include <stdio.h>
    #include <string.h>
    
    struct itinerary
    {
       int flight;                  /* Flight number                */
       char origin_airport[4];      /* Airport of origin            */
       char dest_airport[4];        /* Destination airport          */
       int start_time;              /* Time of start of flight      */
       int arrival_time;            /* Time of arrival              */
    };
    
    static void print_itinerary (struct itinerary const *list, size_t counter)
    {
       size_t i;                    /* Index to cycle through the program   */
    
       for (i = 0; i < counter; i++)
       {
          struct itinerary const *p = list + i;
    
          printf ("Flight:             %d\n", p->flight);
          printf ("Origin Airport:     %s\n", p->origin_airport);
          printf ("Desination Airport  %s\n", p->dest_airport);
          printf ("Start:              %d\n", p->start_time);
          printf ("Arrive:             %d\n", p->arrival_time);
          printf ("\n");
       }
    
       return;
    }
    
    static size_t get_itinerary (struct itinerary *list, size_t nb)
    {
       char line[10];               /* Input from the user                  */
       size_t counter = 0;             /* Counter for loop starts at zero      */
    
       while (counter < nb)
       {
          struct itinerary *p = list + counter;
    
          counter++;
    
          printf ("Enter the flight number      : ");
          fgets (line, sizeof line, stdin);
          sscanf (line, "%d", &p->flight);
    
          printf ("Enter the airport origin     : ");
          fgets (line, sizeof line, stdin);
          *p->origin_airport = 0;
          strncat (p->origin_airport, line, sizeof p->origin_airport - 1);
    
          printf ("Enter the destination airport: ");
          fgets (line, sizeof line, stdin);
          *p->dest_airport = 0;
          strncat (p->dest_airport, line, sizeof p->dest_airport - 1);
    
          printf ("Enter the start time         : ");
          fgets (line, sizeof line, stdin);
          sscanf (line, "%d", &p->start_time);
    
          printf ("Enter the arrival time       : ");
          fgets (line, sizeof line, stdin);
          sscanf (line, "%d", &p->arrival_time);
    
          printf ("Do you wish to enter another flight? (<enter>=yes or n=no) ");
          fgets (line, sizeof line, stdin);
          {
             char quit;             /* Variable used to exit loop           */
             sscanf (line, "%c", &quit);
             if (quit == 'n')
                break;
          }
       }
       return counter;
    }
    
    int main ()
    {
       enum
       {
          MAX_ENTRIES = 50
       };                           /* Max number of stucts to create       */
       struct itinerary list[MAX_ENTRIES];  /* Array of structures for data         */
    
       size_t counter = get_itinerary (list, MAX_ENTRIES);
    
       print_itinerary (list, counter);
       (void) getchar ();
       return 0;
    }
    Emmanuel Delahaye

    "C is a sharp tool"

  11. #11
    Registered User
    Join Date
    Dec 2004
    Posts
    11
    Thanks for all the help guys. I always get a lot out of posting questions here. Yeah, only 2 so far.

    Why do I see quite a few people putting their main function after the other functions in these shorter programs? Is there a good reason for this or is this a style issue?

    Emmanuel Delaha, I really appreciate you taking the time to put that code together for me. I will have to come back to your example later since I have not gotten to pointers yet. Should be there pretty soon if all goes well.

  12. #12
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by silverback011
    Why do I see quite a few people putting their main function after the other functions in these shorter programs? Is there a good reason for this or is this a style issue?
    Putting called functions before the function that calls them saves you from having to prototype the function. Look at these 2 example:
    Code:
    void func2(void)
    {
      // Code goes here
    }
    
    void func1(void)
    {
      func2();
    }
    And then this one:
    Code:
    void func2(void);  // Prototype
    
    void func1(void)
    {
      func2();
    }
    
    void func2(void)
    {
      // Code goes here
    }
    If you don't give the prototype in the second example, the compiler should complain at you about calling an implicitly defined function. But in the first example, the compiler happens upon the called function before the calling function so it already knows how it's defined and you don't need to specify the prototype.

    Since main() is the first function executed, putting it last saves you a lot (sometimes all) prototyping. So yeah, it's pretty much a style thing. Some people like having the prototypes so they can see all of the functions and what they expect/return right at the beginning of the file.

    Make any sense?
    Last edited by itsme86; 12-30-2004 at 05:55 PM.
    If you understand what you're doing, you're not learning anything.

  13. #13
    Registered User
    Join Date
    Dec 2004
    Posts
    11
    Yes, I can see what you mean. I can see the advantages.

    I will try this style to see how it fits me. Right now it seems 'out of order'...if that makes any sense. Maybe that will change after I give it a try.

  14. #14
    Quote Originally Posted by silverback011
    Why do I see quite a few people putting their main function after the other functions in these shorter programs? Is there a good reason for this or is this a style issue?
    The general idea is 'define before use'. Sticking to that makes code easier to write and read.
    Emmanuel Delahaye

    "C is a sharp tool"

  15. #15
    Redundantly Redundant RoD's Avatar
    Join Date
    Sep 2002
    Location
    Missouri
    Posts
    6,331
    >Sticking to that makes code easier to write and read.
    Only if you're talking about a single source file, and then only if the reader thinks the guideline makes sense. Sometimes code is easier to follow if you go from the outside-in rather than from the inside-out. But that's akin to the top-down/bottom-up design methodology controversy, so I'll just say that it's a matter of personal preference and leave it at that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Sorting Linked Lists
    By DKING89 in forum C Programming
    Replies: 6
    Last Post: 04-09-2008, 07:36 AM
  2. Replies: 12
    Last Post: 11-20-2007, 09:35 AM
  3. DOS, Serial, and Touch Screen
    By jon_nc17 in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 01-08-2003, 04:59 PM
  4. what is wrong with this code?
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 05-27-2002, 07:27 PM