Thread: Work in progress

  1. #1
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688

    Work in progress

    Hi the below code is not finished and please excusee the usage of gets() and getch() I will change these in due course. I compiled the below code and saw and error with an array subsript I have never seen before.

    invalid use of array with unspecified bounds
    I have marked on the program where the error lies.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    #define EMPLOYEE_ARRAY_SIZE 10
    #define SALES_ARRAY_SIZE 10
    
    /*function prototype*/
    void companyName ( void );
    void inputEmployeeNames ( char[] );
    void inputSalesFigures ( char[], int, char[][] );
    void sortAndDisplayResults(char[], int, char[][], int, float[] );
    
    /*main function - begins program execution -----------------------------------*/
    int main ( void )
    {
       companyName();
    
       getch(); /*freeze console output window*/
    
       return 0; /*return value from int main*/
    }
    
    /*function to input company namw*/
    void companyName ( void )
    {
       char nameOfCompany[ 80 ];
    
       printf("Enter company name: ");
       gets( nameOfCompany );
    
       inputEmployeeNames ( nameOfCompany );
    }
    
    /*function to read in the employee names*/
    void inputEmployeeNames ( char nmofcmp[] )
    {
       int i;
       char names[ EMPLOYEE_ARRAY_SIZE ][ 50 ];
    
       printf("\n\nEnter the 10 employee names: ");
    
       for ( i = 0; i < EMPLOYEE_ARRAY_SIZE; i++ )
       {
          gets( names[ i ]);
       }
    
       inputSalesFigures ( nmofcmp, EMPLOYEE_ARRAY_SIZE, names );
    }
    
    /*function to read in the sales figures*/
    void inputSalesFigures ( char nmofcmp[], int size, char nameArray[][] )
    {
       int i;
       float sales[ SALES_ARRAY_SIZE ];
    
       printf("\n\nEnter 10 sales figures for the month: ");
    
       for ( i = 0; i < SALES_ARRAY_SIZE; i++ )
       {
          scanf("%f", &sales[ i ]);
       }
    
       sortAndDisplayResults ( nmofcmp, EMPLOYEE_ARRAY_SIZE, nameArray, SALES_ARRAY_SIZE, sales);
    }
    
    /*function to sort arrays into order and display results
      in tabular format*/
    void sortAndDisplayResults ( char nmofcmp[], int size, char nameArray[][], int sizeb, float sal[])
    {
       int i, j;
    
       printf("\n\nCompany Name: %s", nmofcmp);
    
       /*sort names*/
        qsort(( char* ) nameArray, size,  ( *nameArray ), strcmp );
    
       /*sort values*/
       for ( i = 0; i < sizeb -1; i++ )
       {
          for ( j = 0; j < sizeb -1 -i; j++ )
             if ( sal[ j + 1 ] < sal[ j ] )
             {
                int tmp = sal[ j ];
                sal[ j ] = sal[ j + 1 ];
                sal[ j + 1 ] = tmp;
             }
       }
    
       /*display results*/
       printf("\n\nSALES MAN\tTOTAL MADE\n\n");
    
       for ( i = 0; i < size; i++ )
       {
          printf("%s\n", nameArray[ i ]);  // ERROR ON THIS LINE
       }
    
       printf("\n\n");
    
       for ( i = 0; i < sizeb; i++ )
       {
          printf("%.2f\n", sal[ i ]);
       }
    }
    As I have said anything else wrong I will fix myself, but that was the only error my C compiler found at this time and im confused by its meaning. Any help apprecioated. I thought it would be best to post all the code as the error may link to somthing I have done previously.
    Double Helix STL

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Use "fgets" instead of "gets" - that way, if the user types too much, your program won't crash - it may do other things wrong [1] if you don't watch out for "too much input", but at least it won't crash!



    [1] The problem with too much input is that there is a good chance that the next "fgets" reads data left over from the previous read.

    Say for example we have a 5 char string "a" and the user enters the following:
    abcdefghijk<enter>
    We then have a second read of "b", which is 10 chars long.

    "a" will contain "abcd\0"
    "b" will contain "efghijk\n\0"
    But you didn't actually want the "efghijk" stuff, you wanted the NEXT line that the user types...

    There are several suggestions to how you deal with this, try the FAQ How do I Flush the input buffer. Note that this is only useful if you KNOW that there is some "extra" data in the input buffer.

    --
    Mats

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    try changing the function prototype (and of course the function itself later) to something like:
    Code:
    void sortAndDisplayResults(char[], int, char**, int, float[] );

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > qsort(( char* ) nameArray, size, ( *nameArray ), strcmp );
    You need sizeof(*nameArray) for the third argument:
    Code:
        qsort(nameArray, size,  sizeof *nameArray, strcmp );

  5. #5
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    1)

    I think you are getting this error message because the compiler don't know which element correspond to nameArray[i] since nameArray is declared as a 2D char array (in your function sortAndDisplayResults).

    So, what you should do, is to take this
    Code:
    void sortAndDisplayResults ( char nmofcmp[], int size, char nameArray[][], int sizeb, float sal[])
    and modify it to this
    Code:
    void sortAndDisplayResults ( char nmofcmp[], int size, char nameArray[][50], int sizeb, float sal[])
    But using magic number like this is NOT recommended so you should define some constant. Could looks like this

    Code:
    #define LENGTH 50
    ...
    void inputEmployeeNames ( char nmofcmp[] )
    {
       int i;
       char names[ EMPLOYEE_ARRAY_SIZE ][ LENGTH+1 ];
       ...
    }
    ...
    void sortAndDisplayResults ( char nmofcmp[], int size, char nameArray[][LENGTH+1], int sizeb, float sal[])
    {
       ...
    }

    2)

    try changing the function prototype (and of course the function itself later) to something like:
    Code:
    void sortAndDisplayResults(char[], int, char**, int, float[] );
    In fact this won't solve the problem. A 2D array (ex.: char foo[][X]) isn't the same thing as an array of pointer (ex.: char *foo[] or char **foo, even if the later isn't a real array of pointer but a pointer on a pointer but they have one point in common; they can be used the same way).

    Example
    Code:
    char foo[10][15];
    //foo[1][2] is at adress foo + (1 * 15) + 2
    Code:
    char **foo;
    //foo[1][2], apart from being memory we shouldn't acces, is at adress *(foo + 1) + 2
    I don't know if it's clear. It can be a bit confusing. And i'm not 100&#37; sure that i'm right.
    Last edited by foxman; 08-07-2007 at 10:20 PM.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Foxman, a flat array of strings (which is what char *foo[] is) can be expressed as char **foo, there is no difference other than a syntactic one. Really, even if you did supply the first dimension's size, it is still an array of strings where the length of the longest string is specified. The type char** is a compatible one.

    I can't really see where such an example is used in the code that you provided, so here is something I threw together that demonstrates how to sort strings.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int cstr_cmp( const void *s, const void *t )
    {
      const char **u = ( const char** )s, **v = ( const char** )t;
      return strcmp( *u, *v );
    }
    
    int main( void )
    {
      char *names[] = 
      {
        "Anne", "Berry", "Josh", "Preston",
        "Carl", "John", "Jacob", "David",
      }; 
      size_t k, n = sizeof names / sizeof names[0];
    
      qsort( names, n, sizeof( char* ), cstr_cmp );
    
      for ( k = 0; k < n; k++ )
        puts( names[k] );
    
      return 0;
    }
    I hope that you find this informative, swgh.
    Last edited by whiteflags; 08-08-2007 at 01:47 AM. Reason: Semantic didn't seem like the right word, and I checked. It's not.

  7. #7
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    Sorry for not replying before I had some personal business but iv read all the replies and il implment your help in my program. Thanks so much I appreciate all the help given
    Double Helix STL

  8. #8
    Chinese pâté foxman's Avatar
    Join Date
    Jul 2007
    Location
    Canada
    Posts
    404
    Quote Originally Posted by citizen View Post
    Foxman, a flat array of strings (which is what char *foo[] is) can be expressed as char **foo, there is no difference other than a syntactic one.
    I agree with you.

    I just wanted to show that there was a difference between a 2D array and a array of pointer, something that can be ambiguous because they both have related syntax.

    It wasn't clear in my post, but what i wanted to show is that
    Code:
    char foo1[10][15];	// allocate memory for 150 char
    char *foo2[10];		// allocate memory for 10 char *
    char **foo3;		// allocate memory for 1 char **
    are all "different" things a priori. Sure, if you do something like
    Code:
    char **foo3;
    foo3 = malloc (10 * sizeof(char *));
    well, foo3 and foo2 will be equivalent, that's it, they'll both have memory allocated for 10 char *.

    Of course, that's in the case those variables aren't declared in a function header, were it takes a different meaning.
    Code:
    void fct(char *foo1[], char **foo2, char *foo3[10])
    in this case, all those variable are true pointer, since you can't past an "array" (but only an adress) in C.

    I guess this post is clearer.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. getline() don't want to work anymore...
    By mikahell in forum C++ Programming
    Replies: 7
    Last Post: 07-31-2006, 10:50 AM
  2. Why don't the tutorials on this site work on my computer?
    By jsrig88 in forum C++ Programming
    Replies: 3
    Last Post: 05-15-2006, 10:39 PM
  3. Problems in getting OpenGL to work
    By zonf in forum C Programming
    Replies: 5
    Last Post: 02-13-2006, 04:48 AM
  4. progress bars with Win32 API
    By bennyandthejets in forum C++ Programming
    Replies: 15
    Last Post: 09-10-2002, 04:25 AM
  5. DLL __cdecl doesnt seem to work?
    By Xei in forum C++ Programming
    Replies: 6
    Last Post: 08-21-2002, 04:36 PM