Thread: Char arrays and functions

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    111

    Char arrays and functions

    I know I should read more, and I am, but sometimes it helps to get clear example answers to my more or less clear example questions. So, here goes:

    This works:
    Code:
    char *my_strcpy (char *);
    
    int main (int argc, char *argv[]) {
    	char str[64];
    	
    	my_strcpy(str);
            puts(str);
    
    	return 0;
    }
    
    char *my_strcpy(char *dest) {
    	char *p = dest;			
    	
    	// Do something...
    	
    	return dest;
    }
    However, I'm at a loss if my array is an array of strings - a two-dimensional char array.

    This does not work (naturally):
    Code:
    char *my_strcpy (char *);
    
    int main (int argc, char *argv[]) {
    	char str[5][64];
    	
    	my_strcpy(str);
    
    	return 0;
    }
    
    char *my_strcpy(char *dest) {
    	char *p = dest;			
    	
    	// Do something...
    	
    	return dest;
    }
    And neither does this:
    Code:
    char *my_strcpy (char dest[5][64]);
    
    int main (int argc, char *argv[]) {
    	char str[5][64];
    	
    	my_strcpy(str);
     	
    	return 0;
    }
    
    char *my_strcpy(char dest[5][64]) {
    	char *p = dest;  (*)	
    	
    	// Do something...
    	
    	return dest;  (**)
    }
    - "warning: initialization from incompatible pointer type" on line (*)
    - "warning: return from incompatible pointer type" on line (**)

    I'd like to use pointer notation instead of array notation, but at this point I cannot get either to work.

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    p is type char *. dest is char *[64] (1)
    my_strcpy returns char*. you are returning dest which is not a char*
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    111
    Hm...do I need to redefine the my_strcpy() function? If I remove everything inside the function:
    Code:
    char *my_strcpy (char *);
    
    int main (int argc, char *argv[]) {
    	char str[5][64];
    	
    	my_strcpy(str);
     
    	return 0;
    }
    
    char *my_strcpy(char *dest) {
    }
    I get:
    temp.c:9:2: warning: passing argument 1 of ‘my_strcpy’ from incompatible pointer type
    temp.c:4:7: note: expected ‘char *’ but argument is of type ‘char (*)[64]’

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I find it weird that your strcpy knock-off takes only one argument. Standard strcpy takes two, so I'm wondering where the copy part is.

    The type is kinda a non-issue.
    Code:
    my_strcpy(str[0]);
    my_strcpy(str[1]);
    ...
    my_strcpy(str[4]);
    These are all fine.

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    111
    The strcpy name is only because I forgot to change the name from the previous example I worked on. The thing I'm trying to find out is how to do the same as this with a 2-d array:
    Code:
    char *populate (char *);
    
    int main (int argc, char *argv[]) {
    	char str[64];
    	
    	my_strcpy(str);
    
    	return 0;
    }
    
    char *populate (char *dest) {
    	char *p = dest;			
    	
    	// Do something...
    	
    	return dest;
    }
    That is, pass the pointer to a 2-d array to a function which then populates the 2-d array and returns the pointer.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Oh, well the compiler gave you the correct type in the error message. You would just need to name your variable, like char (*foo)[64].

  7. #7
    Registered User
    Join Date
    Nov 2009
    Posts
    111
    Ah, thanks - think I got it now:
    Code:
    char *populate (char (*)[64]);
    
    int main (int argc, char *argv[]) {
    	char str[5][64];
    	
    	populate(str);
        	puts(str[0]);
    	puts(str[1]);	
    
    	return 0;
    }
    
    char *populate(char (*dest)[64]) {
    	char (*p)[64] = dest;			
    
    	strcpy(p[0], "one");
    	strcpy(p[1], "two");
    	
    	return *dest;
    }
    Thanks a heap :-)
    Last edited by cnewbie1; 06-17-2011 at 06:46 AM.

  8. #8
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by cnewbie1
    Code:
    char *populate(char (*dest)[64]) {
    	char (*p)[64] = dest;			
    
    	strcpy(p[0], "one");
    	strcpy(p[1], "two");
    	
    	return *dest;
    }
    You dont have to return anything from this function. As your not changing the base pointer to anything.

    ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Yeah, it doesn't make sense to return that. You could return dest, though the syntax for that is tricky.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  10. #10
    Registered User
    Join Date
    Nov 2009
    Posts
    111
    I thought so too. Also, why should it be necessary to return anything from that function? The array is created in the calling function, and the populate() function populates the array using the pointer.

    I got this from here: A Tutorial on Pointers and Arrays in C
    The author claims that this is "the practice used in the standard routine of returning a pointer to the destination":

    Code:
    int main(void) {
        my_strcpy(strB, strA);
        puts(strB);
    } 
    
    char *my_strcpy(char *destination, char *source) {
       char *p = destination;
       while (*source != '\0') {
          *p++ = *source++;
       }
       *p = '\0';
       return destination;
    }
    In that example, I don't see a reason for returning the destination pointer? The contents of the array is set by the function, by dereferencing the pointer, aren't they?

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Presumably destination is returned because the "real" strcpy also returns the destination pointer.

  12. #12
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    i couldn't work out how to return 2D array. I tried this all the following

    Code:
    char (*)[64] populate( char (*des)[64] );
    char [][64] populate( char (*des)[64] );
    char ** populate( char (*des)[64] );
    all gives me an error :-/ Any ideas?

    ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  13. #13
    Registered User
    Join Date
    Nov 2009
    Posts
    111
    ssharish2005: You're getting and error using the code I pasted? Exactly what are you doing?

  14. #14
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by cnewbie
    ssharish2005: You're getting and error using the code I pasted? Exactly what are you doing?
    I'm trying to return a 2D array from a function. And i was trying to form a function declaration. Thats wasn't from your code.
    ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by ssharish2005 View Post
    I'm trying to return a 2D array from a function. And i was trying to form a function declaration. Thats wasn't from your code.
    ssharish
    C cannot return arrays from functions... it doesn't know how. Inside any function except the one where the array is declared, C does not know how big it is, all size information is lost and without that, it cannot copy the array out to the calling function.

    That is why you mostly see the array's pointer and size passed in the top of the function as parameters.

    Run this small program for an example of why you should never try to return an array from a function...
    Code:
    #include <stdio.h>
    
    int* MyFunction(int a, int b, int c)
      {  static int array[3];
         array[0] = a;
         array[1] = b;
         array[2] = c;
         return array;  } // return a pointer.
    
    
    int main (void)
      { int *a1, *a2;  // int pointers
    
        printf("calling a1 = MyFunction(10,20,30);\t");
        a1 = MyFunction(10,20,30);
        printf("a1 has %d %d %d\n",a1[0],a1[1],a1[2]);
    
        printf("calling a2 = MyFunction(100,200,300);\t");
        a2 = MyFunction(100,200,300);
        printf("a2 has %d %d %d\n",a2[0],a2[1],a2[2]);
    
        printf("\nLooks good, except...\t"); 
        printf("a1 now has %d %d %d\n",a1[0],a1[1],a1[2]);
    
        getchar();
        return 0; }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Char Arrays + Functions + For
    By lautarox in forum C Programming
    Replies: 33
    Last Post: 12-08-2008, 06:35 PM
  2. Replies: 12
    Last Post: 06-06-2008, 05:26 PM
  3. Char to int using functions
    By rachael033 in forum C++ Programming
    Replies: 6
    Last Post: 05-01-2007, 10:10 AM
  4. Passing pointers to arrays of char arrays
    By bobthebullet990 in forum C Programming
    Replies: 5
    Last Post: 03-31-2006, 05:31 AM
  5. Functions returning char arrays
    By turmoil in forum C Programming
    Replies: 3
    Last Post: 05-27-2003, 01:43 AM