简体   繁体   中英

How to pass a string array to a function?

I've declared:

char array_slave_1[128][128];


int array_length(char *a[]){
    int i = 0;
    while(a[i] != NULL){
        i++;
    }
    return i;
}

    int x = array_length(array_slave_1);

I obtain:

main.c:101:26: warning: passing argument 1 of ‘array_length’ from incompatible pointer type [-Wincompatible-pointer-types]
  101 |     int x = array_length(array_slave_1);
      |                          ^~~~~~~~~~~~~
      |                          |
      |                          char (*)[128]
main.c:16:24: note: expected ‘char **’ but argument is of type ‘char (*)[128]’
   16 | int array_length(char *a[]){

I'm not sure if it is correct the way of passing the argument to the function I declared...I think the the problem is this one, but I don't know how to correctly implement the function array_lenght.

char array_slave_1[128][128]

This is 2-dimensional array of char as paramter:

int array_length(char *a[])

This is array of pointers to char (which might be C strings, but could be other char/byte buffers, or single chars too). Except because it is a function parameter, it really is pointer to pointer, so if you are a novice you'd be better off writing what it really is, to avoid getting confused:

int array_length(char **a)

Types of array_slave_1 and a are fundamentally different, and incompatible.


If you want to make your function take the array as parameter, you could do:

int array_length(char a[][128])

which is same as this (note the extra () compared to code in question, they matter,), because array parameters really are pointers, so you have a pointer to one or more char[128] buffers:

int array_length(char (*a)[128])

Then you need a different way to determine the array length , though. Perhaps empty string means end of strings? That's up to you, really.


Alternative is to change your array to be array of pointers:

char *array_slave_1[128]; // 128 pointers to char buffer or C string
// remember that you must allocate the space of each string!

Perhaps you are just "over complicating" things.

Here is a "best guess" at what you might be trying to achieve (based on allocating room for 128x strings, each up to 127 bytes (plus a null terminator.)

#include <stdio.h>
#include <string.h>

int main() {
    char array_slave_1[ 128 ][ 127 + 1 ]; // notation helps signify this is a string

    strcpy( array_slave_1[ 0 ], "Hello World!" );
    strcpy( array_slave_1[ 1 ], "Foobar" );

    for( int i = 0; i < 2; i++ )
        printf( "'%s' length %d\n", array_slave_1[ i ], strlen( array_slave_1[ i ] ) );

    return 0;
}

Output

'Hello World!' length 12
'Foobar' length 6

strlen() has already been done in the standard C library.

  • char array_slave_1[128][128]; is an array of arrays of char , often called 2D array.
  • char *a[] is an array of pointers to char . It is not compatible with a 2D array.

When an array in C used in most expressions, or when declared as a function parameter, it "decays" into a pointer to it's first element.

  • For a plain char array[x] , the first element is char and so it decays to a pointer to char : char* .
  • For an array of arrays char array[x][y] , the first element is an array char [y] . So it decays into a pointer to such an array, char (*)[y] . This decay happens to the array you pass as argument, as well as to any 2D array declared as function parameter.

Thus:

void func (char array[128][128]);
...
char array [128][128];
func(array);

Which is 100% equivalent to:

void func (char (*array)[128]);
...
char array [128][128];
char(*ptr)[128] = array;
func(array);

So for accepting a 2D array, you may declare the function using either of the above equivalent forms, though the latter is less readable. The most generic and readable form of all might however be a variable-length array:

void func (size_t x, size_t y, char array[x][y]);

Please also note that while(a[i] != NULL) will only work for arrays of pointers , where the last pointer was assigned to NULL, a so-called "sentinel value". You cannot use this unless you keep the function as char* arr[n] and then pass an array of pointers as argument instead.

How to pass a string array to a function?

That depends on what you mean by "string array", because it turns out that there are, sort of, two completely different types of "string" in C. Formally, a string is an array of characters. But since arrays almost always decay into pointers when you use them, it is extremely common to think about char * — that is, pointer-to- char — as also being a "string type" in C.

char array_slave_1[128][128];

This is an array of arrays of char . So it is usefully an array of strings, using the array definition of "string". It does have the limitation that none of the strings it contains can ever be longer than 127 characters.

int array_length(char *a[]) {...

This function accepts an array of pointers to char . So it is also usefully an array of strings, using the pointer definition of "string". It is further apparent that you are trying to use an array of pointers here given that you are looking for a NULL pointer to mark the end of the array.

But! In this case, the two different types of "array of string" are not compatible. An array of arrays is completely different from an array of pointers, There are no automatic conversions that will let you start with one. and treat it as if it was the other.

(This is by contrast to the situation with simple, single strings, since the array-decay-to-pointer rule always lets you treat an array-string as if it were a pointer-string.)

Your best bet is probably to change

char array_slave_1[128][128];

to

char *array_slave_1[128];

Now you have an array of 128 pointer-strings. This will be compatible with your array_length function, and it will remove the limitation on the lengths of the individual strings in the array. On the other hand, you will need to change any code you have for initializing and manipulating the string in array_slave_1 : Some of that code may still be fine, but anything that involves something like strcpy(array_slave_1[i], ...) will have to change. Depending on your needs, you may also need to call malloc to allocate space for each element in the array to point to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM