8

I want to implement the following function to print the contents of several char strings which are referenced through a pointer array. How can I determine how many pointers there are without passing the total as an argument of the function?

If it was an array of type int then it would be possible to use the sizeof() function but given that each item of my array is a pointer to a char string and each string could be of different length I don't think I can use this approach.

void printCharArray(char *arr[]){

    int length = sizeof(arr) / sizeof(char); /* this does not give correct 
                                          number of items in the pointer array */

    for (int i=1;i<=length; i++) {
        printf("Array item: [%s]",arr[i]);
    }

}
  • "How can I determine how many pointers there are without passing the total as an argument of the function?" – you can't. This is why every function that writes into arrays in the stdlib takes a count argument. – millimoose Dec 24 '12 at 00:56

5 Answers5

14

There is no built-in way to do this as C does not track the number of elements in an array for you like this.

You have a couple of options:

  1. Pass the number of items in the array.
  2. Set the last item to NULL so the code knows when it's reached the end. (This is kind of how C strings are handled.)
  3. Otherwise modify your data structures to track the number of items in the array.
Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
6

You cannot pass arrays as function arguments in C. Array names decay to pointers to their first element when used as a function argument, and you must separately specify the number of available array elements.

(In the context of a function parameter type, T[] and T* and T[12] are identical, so your function paramter might as well be char ** arr.)

Like so:

void printCharArray(char ** arr, size_t len) { /* ... */ }

int main()
{
    char * arr[10] = { "Hello", "World", /* ... */ };

    printCharArray(arr, sizeof(arr)/sizeof(*arr));
}

(Alternatively you can supply a "first" and a "one-past-the-end" pointer, which might be a bit more natural.)

Community
  • 1
  • 1
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • That's interesting, so `sizeof(arr)` will give the size of the memory occupied by the pointer to the whole array and `sizeof(*arr)` will give the size occupied by a pointer to an item in the array which in this case is a pointer of a char string? –  Dec 24 '12 at 01:10
  • Could the size calculation be done inside the printCharArray() function body? –  Dec 24 '12 at 01:13
  • 2
    @NSDigital No, in `printCharArray()`, there is no array, only a pointer. You can calculate the size that way **only for real arrays**, not for pointers, even if they point to the first element of an array. – Daniel Fischer Dec 24 '12 at 01:54
  • 1
    @NSDigital: `sizeof` for *arrays* gives you the entire size, but inside the function *there is no array*. There is only a pointer. – Kerrek SB Dec 24 '12 at 08:32
2

If you set the element after the last valid element to null then you can do:

void printCharArray(char *arr[]){

    for (int i=0; arr[i] != NULL; i++) {
        printf("Array item: [%s]",arr[i]);
    }

}
perreal
  • 94,503
  • 21
  • 155
  • 181
0
void printCharArray(char *arr[]) {
    int length = sizeof(arr) / sizeof(char*); /* this does not give correct 
                                                 number of items in the pointer array */
    for (int i=0;i<=length; i++) {
        printf("Array item: [%s]",arr[i]);
    }
}

int main()
{
    char * arr[10] = { "Hello", "World", /* ... */ };
    printCharArray(arr); 
}
Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
sharingli
  • 138
  • 1
  • 7
0

first I declared y as a global var. htmTags is a *char[]. then in main()

y = 0;
while( htmTags[y] ) {
        y++;
}

I did not add null at the end of array. provides actual count of array elements

or this works too for (y=0;htmTags[y];y++) ;

James Danforth
  • 781
  • 7
  • 7