Thread: Passing an array of strings to a function.

  1. #1
    Registered User
    Join Date
    Sep 2009
    Posts
    3

    Passing an array of strings to a function.

    Hi,

    I have actually (sort of) figured out how to do this. By passing wach string in the array separately to a function that accepts a string. But I actually want it to pass a whole array of char[x][y] to a function in one smack and have my loops inside the function instead. I think i have been confused by the pointers somehow.

    This works, but its not exactly what I want to do:

    Code:
    #include <stdio.h>
    
    void printmatrixline(char *matrix);
    
    char first[20][21] = {
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    };
    
    int main () {
    	int i;
    	for(i=0; i < 20; i++) {
    		printmatrixline(first[i]);
    	}
    	printf("\n");
    }
    
    void printmatrixline(char *matrix) {
    	int i;
    	for (i=0; i < 20; i++) {
    		printf("%c", matrix[i]);
    	}
    	printf("\n");
    }
    This is what I want to do, but it doesn't work.

    Code:
    #include <stdio.h>
    
    void printmatrix(char *matrix);
    
    char first[20][21] = {
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    	"....................",
    };
    
    int main () {
    	printmatrix(first);
    	printf("\n");
    }
    
    void printmatrix(char *matrix) {
    	int i,j;
    	for (i=0; i < 20; i++) {
    		for (j=0; j < 20; j++) {
                    printf("%c", matrix[i][j]);
                    }
    	}
    	printf("\n");
    }
    I can successfully pass a pointer to a string using *string but I cant pass an array of strings OR and array of an array of characters by using *array. Any help?

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Yeah, this is kind of a weird issue IMO. A hassle, in fact. You want to pass EITHER a pointer to a pointer:

    void printmatrix(char **matrix);

    OR this:

    void printmatrix(char matrix[][21]);

    However, to use the first version, you will have to do something slightly convoluted:
    Code:
    char *ptray[20];
    for (i=0;i<20;i++) ptray[i]=first[i];
    printmatrix(ptray);
    Either way, you can now access matrix[x] (and matrix[x][x]) in printmatrix.
    Last edited by MK27; 09-16-2009 at 02:56 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Sep 2009
    Posts
    3
    Thanks for your help, the second option worked.

    I am curious as to how the first one works. As i think this is supposed to be the best practice. I assume that the code you wrote goes in the main function and not the void function.

    char *ptray[20];
    for (i=0;i<20;i++) { ptray[i]=first[i]; }
    printmatrix(ptray);

    I also assume that this code creates another variable that points to an array in an array(in this case a string in an array as my first ends each line in a '\0'.

    So when "void printmatrix(char **matrix);" is used then the first * points to an array called ptray which is the array of array of characters, and the second * points to the char in the array. amirite?

    This is quite confusing.

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    I am curious as to how the first one works.
    Declare your array like this:
    Code:
    char* first[] = {
    And rename your printmatrix prototype to:
    Code:
    void printmatrix(char **matrix)
    bit∙hub [bit-huhb] n. A source and destination for information.

  5. #5
    Registered User
    Join Date
    Mar 2007
    Posts
    142
    Try this version:

    Code:
    #include <stdio.h>
    
    void printmatrix (char **matrix);
    
    char *first[20] = {
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    "....................",
    };
    
    int main (int argc, char *argv[])
    {
       printmatrix (first);
       printf("\n");
    }
    
    void  printmatrix (char **matrix)
    {
       int  i, j;
       
       for (i=0; i < 20; i++)  {
          for (j=0; j < 20; j++)  {
             printf ("%c", matrix[i][j]);
          }
          printf("\n");
       }
    }
    ---

    EDIT: Ah, bithub did the same thing.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    There are two problems with bithub's method. One is that if the pre-populated entries in the matrix are not all the same length (21 characters), you are stuck with a jagged array:

    Code:
    char *matrix[3] = {"one", "seventeen", "a mouse in the house"};
    Each string will only be allocated it's length, so is you are performing operations on each row, be careful to use strlen() and not 21.

    The other is that these are now string literals and so CANNOT be altered.

    Otherwise, of course, it is easier.
    Last edited by MK27; 09-16-2009 at 04:19 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    No, it's an array of pointers to characters, not a pointer to an array of characters. You can't actually change the contents of "one", because it's a string literal. You instead must make it point to something else.


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

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by dazman19 View Post
    Thanks for your help, the second option worked.

    1) I am curious as to how the first one works. As i think this is supposed to be the best practice. I assume that the code you wrote goes in the main function and not the void function.

    2) I also assume that this code creates another variable that points to an array in an array(in this case a string in an array as my first ends each line in a '\0'.

    3) So when "void printmatrix(char **matrix);" is used then the first * points to an array called ptray which is the array of array of characters, and the second * points to the char in the array. amirite?
    1) Yes, that for() loop would go somewhere OUTSIDE of printmatrix(**matrix). I would not say this is the best practice, it is more of a clue (but it is not too bad either). Normally you would declare one **matrix, then allocate and populate each of it's rows, so that you would not have to have two variables. None of that is necessary if the parameter to printmatrix() is always the same size ([20][21]); it is only necessary if printmatrix() is going to accept any 2D matrix of any size -- printmatrix(**matrix).

    2) Yes. **ptp is actually a one dimensional array of pointers, each of which corresponds to a row in matrix[20][21].

    3) I think what ** means is that the location pointed to contains more pointers, hence, a "pointer to a pointer". I do not think about it in terms of the meaning of each individual asterisk.
    Last edited by MK27; 09-16-2009 at 04:11 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Quote Originally Posted by Quzah
    You can't actually change the contents of "one", because it's a string literal. You instead must make it point to something else.
    Yep. In fact, I should have declared it as "const" in my example.
    bit∙hub [bit-huhb] n. A source and destination for information.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by bithub View Post
    Yep. In fact, I should have declared it as "const" in my example.
    Ah! That's probably why I never do that. I'll edit that post.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Sep 2009
    Posts
    3
    1) Yes, that for() loop would go somewhere OUTSIDE of printmatrix(**matrix). I would not say this is the best practice, it is more of a clue (but it is not too bad either). Normally you would declare one **matrix, then allocate and populate each of it's rows, so that you would not have to have two variables. None of that is necessary if the parameter to printmatrix() is always the same size ([20][21]); it is only necessary if printmatrix() is going to accept any 2D matrix of any size -- printmatrix(**matrix).
    I dont really want to write a loop around the function every time I want to call it.
    I had written a loop around my function and passed a pointer to the strings in the first instance. I have no trouble understanding this. I may do myself some justice doing some reading up on pointers in C.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. function passing argument..array ?
    By jochen in forum C Programming
    Replies: 2
    Last Post: 09-30-2007, 11:53 AM
  2. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. passing array of structures to function
    By bvnorth in forum C Programming
    Replies: 3
    Last Post: 08-22-2003, 07:15 AM