Thread: passing arrays of structs :(

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    10

    Unhappy passing arrays of structs :(

    Ok i have a program that must pass an array of structures to be operated on. Below I have the code for the function prototype, the declaration of each part, and the function call. The error I am getting is:
    'manual' : cannot convert parameter 1 from 'main::crypt *' to 'crypt[]'

    Code:
    void manual( struct crypt [], char []);      <-- function prototype
    
    int main()
    {
        struct crypt{char encoded; char decoded;};
        struct crypt key[]={ key is initialized properly without errors};
      ....
    blah
    ....
    manual( key , message );        <-- function call
    ...
    blah
    ...
    return;
    }
    So i'm trying to send it key, which is an array of structs, and message, which is just a string. Any help on what I'm missing would be great before I lose any more hair

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Key[] has no size, so that's #1 problem. Your compiler should be complaining about this. Are you using a C++ compiler, by chance, instead of a C compiler?

  3. #3
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    Quote Originally Posted by Adak View Post
    Key[] has no size, so that's #1 problem. Your compiler should be complaining about this. Are you using a C++ compiler, by chance, instead of a C compiler?
    the compiler will make Key large enough to hold the value it's initialized to (which looks like 1 in this case)


    change: void manual( struct crypt [], char []);
    to: void manual( struct crypt *, char []);
    and maybe even: void manual( struct crypt *, char *);

    you can still treat it as if it was an array
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    10
    dear ಠ_ಠ, I have actually tried both of those. Changing array to pointer and vice versa, but I end up with the same error. and yes the compiler does allocate the space for key because it's initialized in the definition.

    changing between * and [] changes the phrasing of the error slightly from
    'manual' : cannot convert parameter 1 from 'main::crypt *' to 'crypt[]'
    to
    'manual' : cannot convert parameter 1 from 'main::crypt *' to 'crypt *'
    or
    'manual' : cannot convert parameter 1 from 'main::crypt []' to 'crypt[]'

    Any other ideas
    thanks for your input so far

    and to Adak, yes I am using a C++ compiler, visual studio 2008. Is there something about that that would cause a problem?

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    and to Adak, yes I am using a C++ compiler, visual studio 2008. Is there something about that that would cause a problem?
    Oh yeah! Set the options in VS to compile *.c programs with the C compiler it has, not the C++. Make sure your programs have a dot c extension on them.

    Then post your latest code, and I'll take it for a test drive.

  6. #6
    Registered User
    Join Date
    Mar 2009
    Posts
    10
    I'm having trouble finding where to switch the compile preference ? (I just switched from 2003 to 2008).

    Here is enough of the code to test build it and get the error.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    void end_game( char * );
    void manual( struct crypt [] , char *, int );
    void auto_guess( struct crypt [] , char * , char [] );
    int main()
    {
    	int i,j;
    	char *file, *message;
    	char ch,kiwi;
    	char freq[26]={'e','t','a','o','i','n','s','h','r','d','l','c','u','m','w','f','g','y','p','b','v','k','j','x','q','z'};
    	char name[80]={'\0'};
    	struct crypt{char encoded; char decoded;};
    	struct crypt key[] =
    	{{'a','-'},{'b','-'},{'c','-'},{'d','-'},{'e','-'},{'f','-'},{'g','-'},{'h','-'},{'i','-'},{'j','-'},{'k','-'},
    	{'l','-'},{'m','-'},{'n','-'},{'o','-'},{'p','-'},{'q','-'},{'r','-'},{'s','-'},{'t','-'},{'u','-'},{'v','-'},
    	{'w','-'},{'x','-'},{'y','-'},{'z','-'}};
    	FILE *fp;
    
    	printf("************************************************************************ \n");
    	printf("**             WELCOME!!!! TO THE DECODER!!!                          ** \n");
    	printf("************************************************************************ \n \n");
    	printf("Would you like to play a game? (Y or N): ");
    	scanf("%c", &ch);
    	if( ch == 'N' || ch == 'n' )
    	{
    		printf("\nFarwell!! \n");
    		getchar();
    		exit(0);
    	}
    	printf("Please input a filename where the encrypted message is contained: \n");
    	scanf("%s", name);
    	/* Now to find how long the file is, note: this will include carriage returns initially */
    	fseek( fp , 0 , SEEK_END );
    	i = ftell( fp );  /* i is length of file */
    	
    	/* get file into dynamically allocated array of correct size */ 
    	file = (char *)calloc( i , sizeof(char) );
    	fseek( fp , 0 , SEEK_SET );
    	j = fread( file , sizeof(char) , i , fp );
    	message = (char *)calloc( j , sizeof(char) );
    	strcpy( message , file );
    	free( file );
    
    	/* Now the file is in the array, the key is initialized */
    	while( i != 3 )
    	{
    		printf("Encoded letter: ");
    			for( i=0 ; i<26 ; i++ )
    		{
    			printf(" %c", key[i].encoded);
    		}
    		printf("\n\nDecoded letter: ");
    		for( i=0 ; i<26 ; i++ )
    		{
    			printf(" %c", key[i].decoded);
    		}
    		printf("\n\n");
    
    		/* Apply messge based on current key */
    		/* so if dash, leave as is, if decodes to, then replace with CAP decoded */
    
    		puts( message );
    		
    		
    		printf("\n\n");
    		printf("You have three options!\n1) Manually Replace one encrypted letter with a letter of your choice (type 1)\n 2)\
    			   Perform auto-guess which will use freq analysis to try and improve the encrpted file (type 2)\n3)End the Game\
    			   (type 3)\n Enter your choice: ");
    		scanf("%d",i);
    		switch(i)
    		{
    		case 1: manual( k , message , j );
    				break;
    		case 2: auto_guess( k , message , freq );
    				break;
    		case 3: end_game( message );
    				break;
    		default: printf("Invalid choice");
    				break;
    		} 
    	}
    		
    		
    		getchar();
    	return 0;
    
    }
    
    void manual( struct crypt key[] , char *message , int n )
    {
    	printf("With manual replace you may choose an encrypted letter and the letter you want to decode it to.\nPlease enter \
    		   the encrypted letter for which you want to change the decoded letter(lower-case): ");
    	scanf("%c",ch);
    	printf("Now enter the letter you want your choice to decode to(lower-case): ");
    	scanf("%c", kiwi);
    	return;
    }
    I tried to cut out at least some of the non-necessary bits

  7. #7
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    Code:
    void manual( struct crypt key[] , char *message , int n )
    {
    	printf("With manual replace you may choose an encrypted letter and the letter you want to decode it to.\nPlease enter \
    		   the encrypted letter for which you want to change the decoded letter(lower-case): ");
    	scanf("%c",ch);
    	printf("Now enter the letter you want your choice to decode to(lower-case): ");
    	scanf("%c", kiwi);
    	return;
    }
    you never declared ch or kiwi
    Last edited by ಠ_ಠ; 04-05-2009 at 12:38 AM.
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This version of your program compiles, but I can't run it without all the rest of it. Check it out.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct crypt{
    char encoded; char decoded;
    };
    
    
    void end_game( char * );
    void manual( struct crypt [] , char *, int );
    void auto_guess( struct crypt [] , char * , char [] );
    int main()
    {
    	int i,j;
    	char *file, *message;
    	char ch, kiwi;
    	char freq[26]={'e','t','a','o','i','n','s','h','r','d','l','c','u','m','w','f','g','y','p','b','v','k','j','x','q','z'};
    	char name[80]={'\0'};
    
    	struct crypt key[] =
    	{{'a','-'},{'b','-'},{'c','-'},{'d','-'},{'e','-'},{'f','-'},{'g','-'},{'h','-'},{'i','-'},{'j','-'},{'k','-'},
    	{'l','-'},{'m','-'},{'n','-'},{'o','-'},{'p','-'},{'q','-'},{'r','-'},{'s','-'},{'t','-'},{'u','-'},{'v','-'},
    	{'w','-'},{'x','-'},{'y','-'},{'z','-'}};
    	FILE *fp;
    
    	printf("************************************************************************ \n");
    	printf("**             WELCOME!!!! TO THE DECODER!!!                          ** \n");
    	printf("************************************************************************ \n \n");
    	printf("Would you like to play a game? (Y or N): ");
    	scanf("%c", &ch);
    	if( ch == 'N' || ch == 'n' )
    	{
    		printf("\nFarwell!! \n");
    		ch = getchar();
    		exit(0);
    	}
    	printf("Please input a filename where the encrypted message is contained: \n");
    	scanf("%s", name);
    	/* Now to find how long the file is, note: this will include carriage returns initially */
    	fseek( fp , 0 , SEEK_END );
    	i = ftell( fp );  /* i is length of file */
    	
    	/* get file into dynamically allocated array of correct size */ 
    	file = (char *)calloc( i , sizeof(char) );
    	fseek( fp , 0 , SEEK_SET );
    	j = fread( file , sizeof(char) , i , fp );
    	message = (char *)calloc( j , sizeof(char) );
    	strcpy( message , file );
    	free( file );
    
    	/* Now the file is in the array, the key is initialized */
    	while( i != 3 )
    	{
    		printf("Encoded letter: ");
    			for( i=0 ; i<26 ; i++ )
    		{
    			printf(" %c", key[i].encoded);
    		}
    		printf("\n\nDecoded letter: ");
    		for( i=0 ; i<26 ; i++ )
    		{
    			printf(" %c", key[i].decoded);
    		}
    		printf("\n\n");
    
    		/* Apply messge based on current key */
    		/* so if dash, leave as is, if decodes to, then replace with CAP decoded */
    
    		puts( message );
    		
    		
    		printf("\n\n");
    		printf("You have three options!\n1) Manually Replace one encrypted letter with a letter of your choice (type 1)\n 2)\
    			   Perform auto-guess which will use freq analysis to try and improve the encrpted file (type 2)\n3)End the Game\
    			   (type 3)\n Enter your choice: ");
    		scanf("%d",i);
    		switch(i)
    		{
    		case 1: manual( key , message , j );
    				break;
    		case 2: auto_guess( key , message , freq );
    				break;
    		case 3: end_game( message );
    				break;
    		default: printf("Invalid choice");
    				break;
    		} 
    	}
    		
    		
    	i = getchar();
    	return 0;
    
    }
    
    void manual( struct crypt key[] , char *message , int n )
    {
       char ch, kiwi;
    
    	printf("With manual replace you may choose an encrypted letter and the letter you want to decode it to.\nPlease enter \
    		   the encrypted letter for which you want to change the decoded letter(lower-case): ");
    	scanf(" %c",ch);
    	printf("Now enter the letter you want your choice to decode to(lower-case): ");
    	scanf(" %c", kiwi);
    	return;
    }

  9. #9
    Registered User Sharke's Avatar
    Join Date
    Jun 2008
    Location
    NYC
    Posts
    303
    So basically the only thing wrong was that he declared the struct inside the function, meaning its tag couldn't be used in another function? (Forgetting about passing the mysterious 'k' instead of 'key' for a minute!)

  10. #10
    Registered User Sharke's Avatar
    Join Date
    Jun 2008
    Location
    NYC
    Posts
    303
    Quote Originally Posted by Adak View Post
    Oh yeah! Set the options in VS to compile *.c programs with the C compiler it has, not the C++. Make sure your programs have a dot c extension on them.

    Then post your latest code, and I'll take it for a test drive.
    I was under the impression that all you had to do was name your source files with a dot c extension and VS would compile them as C automatically - no need for any changes in settings. That's what I've been doing anyway.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Sharke View Post
    So basically the only thing wrong was that he declared the struct inside the function, meaning its tag couldn't be used in another function? (Forgetting about passing the mysterious 'k' instead of 'key' for a minute!)
    In maual(), ch and kiwi were not defined, and for my compiler at least, you can't reference a struct by name, even in a function prototype, before said struct has been defined for the compiler. You can subsequently declare an instance of the struct, anywhere you want, within the scope.

    @Sharke:
    I believe that is the default, but I have no idea how he has his options set. Since he can't find the options, it may well be still in default mode, where dot c programs are compiled by the C compiler.

    So a few problems and potential problems have been sorted out, at least.
    Last edited by Adak; 04-05-2009 at 01:25 AM.

  12. #12
    Registered User
    Join Date
    Mar 2009
    Posts
    10
    I'd like to apologize both for where it's passing k instead of key and the fact that ch and kiwi were not defined in manual. I've been editing more than I should trying to resolve the error, and writing more code in the meantime without the proper attention.

    I did declare the struct as a global now, and the cannot conver error is gone so THANK YOU very much for that. However my professor is vehemently against globals, as ridiculous as that is. I will use the global but is there anyway to avoid it?

  13. #13
    Banned ಠ_ಠ's Avatar
    Join Date
    Mar 2009
    Posts
    687
    global structs are fine, global variables ARE NOT
    ╔╗╔══╦╗
    ║║║╔╗║║
    ║╚╣╚╝║╚╗
    ╚═╩══╩═╝

  14. #14
    Registered User Sharke's Avatar
    Join Date
    Jun 2008
    Location
    NYC
    Posts
    303
    Quote Originally Posted by Tbrez View Post
    I'd like to apologize both for where it's passing k instead of key and the fact that ch and kiwi were not defined in manual. I've been editing more than I should trying to resolve the error, and writing more code in the meantime without the proper attention.

    I did declare the struct as a global now, and the cannot conver error is gone so THANK YOU very much for that. However my professor is vehemently against globals, as ridiculous as that is. I will use the global but is there anyway to avoid it?
    Declaring a structure definition externally is not the same as initializing a global variable. You still declare the key[] array of structs within main(), so that's not global. You would normally put a struct definition in a header file along with function prototypes.

  15. #15
    Registered User
    Join Date
    Mar 2009
    Posts
    10
    duly noted. I think I'm up to speed now. Y'all are lifesavers, thanks again

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. More trouble passing arrays
    By Rad_Turnip in forum C Programming
    Replies: 2
    Last Post: 04-04-2006, 08:11 PM
  2. Replies: 6
    Last Post: 04-26-2004, 10:02 PM
  3. Help Understanding Passing Arrays To Functions
    By jrahhali in forum C++ Programming
    Replies: 7
    Last Post: 04-10-2004, 02:57 PM
  4. passing structs to functions?
    By Neildadon in forum C++ Programming
    Replies: 1
    Last Post: 12-13-2002, 04:31 PM
  5. passing arrays to functions
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 03-01-2002, 03:18 PM

Tags for this Thread