48
char* names[]={"A", "B", "C"};

Is there a way to find the number of strings in the array? For example, in this case it should output: 3.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
user1128265
  • 2,891
  • 10
  • 29
  • 34
  • 2
    This is a specific case of how to get the size of an array, which already has a general answer here: https://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c I.e. a duplicate. – this Oct 15 '15 at 13:10

9 Answers9

48

For an array, which the examples in the bounty are, doing sizeof(names)/sizeof(names[0]) is sufficient to determine the length of the array.

The fact that the strings in the examples are of different length does not matter. names is an array of char *, so the total size of the array in bytes is the number of elements in array times the size of each element (i.e. a char *). Each of those pointers could point to a string of any length, or to NULL. Doesn't matter.

Test program:

#include<stdio.h>

int main(void)
{
    char* names1[]={"A", "B", "C"}; // Three elements
    char* names2[]={"A", "", "C"}; // Three elements
    char* names3[]={"", "A", "C", ""}; // Four elements
    char* names4[]={"John", "Paul", "George", "Ringo"}; // Four elements
    char* names5[]={"", "B", NULL, NULL, "E"}; // Five elements

    printf("len 1 = %zu\n",sizeof(names1)/sizeof(names1[0]));
    printf("len 2 = %zu\n",sizeof(names2)/sizeof(names2[0]));
    printf("len 3 = %zu\n",sizeof(names3)/sizeof(names3[0]));
    printf("len 4 = %zu\n",sizeof(names4)/sizeof(names4[0]));
    printf("len 5 = %zu\n",sizeof(names5)/sizeof(names5[0]));
}

Output:

len 1 = 3
len 2 = 3
len 3 = 4
len 4 = 4
len 5 = 5

EDIT:

To clarify, this only works if you've defined an array, i.e. char *names[] or char names[][], and you're in the scope where the array was defined. If it's defined as char **names then you have a pointer which functions as an array and the above technique won't work. Similarly if char *names[] is a function parameter, in which case the array decays to the address of the first element.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 2
    Thank you. The explanation that you give is excellent, and it is the key. I suppose based on the explanation that cnicutar's answer should be the _accepted answer_, as it gives the same answer but without explanation, but this answer so far is the leading candidate for the bounty. Thank you. – dotancohen Oct 14 '15 at 16:08
  • 1
    what happens if the array is empty? – Niels Jul 10 '18 at 07:51
  • 1
    @Niels arrays with 0 elements are not allowed by the standard. – dbush Jul 10 '18 at 10:41
  • What is the solution for `const char **`? – IC_ Apr 08 '23 at 04:39
48

In this case you can divide the total size by the size of the first element:

num = sizeof(names) / sizeof(names[0]);

Careful though, this works with arrays. It won't work with pointers.

cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 3
    Many code bases define this as a macro something like: #define ARRAY_SIZE(x) ( sizeof(x) / sizeof((x)[0]) ) – Matt Liberty Oct 14 '15 at 20:35
  • This answer should be the accepted answer. It was the first answer, and it is correct. That said, _the bounty_ I'm awarding to the first answer that explained why this works. – dotancohen Oct 21 '15 at 15:41
  • I tried sizeof with my array array[]={".A.","..B",".C.",".D.","..E",} I get count 3 of 5 ..... with sizeof AND strlen –  Mar 15 '17 at 13:58
  • I get : invalid application of 'sizeof' to incomplete type 'const char *[]' – Phil Jul 29 '20 at 12:13
19

It depends on how your array is created. In C, there is no way to check the length of an array that is a pointer, unless it has a sentinel element, or an integer passed with the array as a count of the elements in the array. In your case, you could use this:

int namesLen = sizeof(names) / sizeof(char);

However, if your array is a pointer,

char **names = { "A", "B", "C" };

You can either have an integer that is constant for the length of the array:

int namesLen = 3;

Or add a sentinel value (e.g. NULL)

char **names = { "A", "B", "C", NULL };

int namesLen = -1;
while (names[++namesLen] != NULL) { /* do nothing */}

// namesLen is now the length of your array

As another way, you could create a struct that is filled with the values you want:

struct Array {
    void **values;
    int length;
};

#define array(elements...) ({ void *values[] = { elements }; array_make(values, sizeof(values) / sizeof(void *)); })
#define destroy(arr) ({ free(arr.values); })

struct Array array_make(void **elements, int count)
{
    struct Array ret;
    ret.values = malloc(sizeof(void *) * count);
    ret.length = count;

    for (int i = 0; i < count; i++) {
        ret.values[i] = elements[i];
    }

    return ret;
}

And you would use it as such:

struct Array myArray = array("Hi", "There", "This", "Is", "A", "Test");
// use myArray

printf("%i", myArray.length);
destroy(myArray);
Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
12

What you're defining here isn't literally an array of strings , it's an array of pointers to characters. if you want to know the number of strings, you simply have to count the pointers, so something like

size_t size = sizeof(names)/sizeof(char*);

would do,this way you're dividing the size of the array by the size of a single pointer.But be aware this only works if the size of the array is known at compile time(i.e. the array is allocated statically), if it's defined dynamically (i.e. char** strings) then sizeof(strings) would return the size of the pointer not the array.

p.s.:the length of the strings is not relevant, as the array isn't even "aware" of what the pointers point to.

hassan arafat
  • 657
  • 5
  • 15
2

Is there a way to find the number of strings in the array

Of course there is, try this:

#include<stdio.h>

int main(void){
    size_t size, i=0;
    int count=0;
    char* names[]={"A", "B", "C"};

    size = sizeof(names)/sizeof(char*);

    for(i=0;i<size;i++){
        printf("%d - %s\n",count+1, *(names+i));
        count++;
    }

    printf("\n");
    printf("The number of strings found are %d\n",count);
    return 0;
}
1 - A
2 - B
3 - C
The number of strings found are 3

Same thing with:

#include<stdio.h>

int main(void){
    size_t size, i=0;
    int count=0;
    char *names[]={"Jimmy", "Tom", "Michael", "Maria", "Sandra", "Madonna"};

    size = sizeof(names)/sizeof(char*);

    for(i=0;i<size;i++){
        printf("%d - %s\n",count+1, *(names+i));
        count++;
    }

    printf("\n");
    printf("The number of strings found are %d\n",count);
    return 0;
}

Output:

1 - Jimmy
2 - Tom
3 - Michael
4 - Maria
5 - Sandra
6 - Madonna
The number of strings found are 6

Or use a Function like this:

#include<stdio.h>

size_t arrLength(size_t len, char **arr){
    size_t i=0;
    size_t count=0;

    for(i=0;i<len;i++){
        printf("%zu - %s\n",count+1, *(arr+i));
        count++;
    }

    return count;
}

int main(void){
    char *names[]={"Jimmy", "Tom", "Michael", "Maria", "Sandra", "Madonna"};
    size_t length,size;

    size = sizeof(names)/sizeof(char*);
    length = arrLength(size, names);

    printf("\n");
    printf("The number of strings found are %zu\n",length);
    return 0;
}

Output:

1 - Jimmy
2 - Tom
3 - Michael
4 - Maria
5 - Sandra
6 - Madonna
The number of strings found are 6
Michi
  • 5,175
  • 7
  • 33
  • 58
  • This seems rather silly. The `arrLength` function isn't computing anything other than the size already passed into it. – Chris Jul 12 '23 at 05:39
1
int count = sizeof(names)/sizeof(*names);

This takes the total size of names and divides it by the size of one element in names, resulting in 3.

Marlon
  • 19,924
  • 12
  • 70
  • 101
  • 1
    "does not work with dynamically allocated memory". More specifically, it does not work if the array (contrasted with "the members of the array") has been dynamically allocated. Since this is an array of pointers, the distinction needs to be made. – Robᵩ Mar 01 '12 at 19:41
0

find the number of strings in an array of strings in C

The simple method to find the number of objects in an array is to take the size of the array divided by the size of one of its elements. Use the sizeof operator which returns the object's size in bytes.

// For size_t
#include <stddef.h>

char* names[] = { "A", "B", "C" };
size_t number_of_strings = sizeof names / sizeof names[0];

printf("Number of strings %zu\n", number_of_strings);

Important to consider the type return from sizeof is size_t, an unsigned integer type capable of indexing any array as well as the size of any object. To print a variable of type size_t, use the modifier z.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
-1

One simple way to return the number or strings in an array is to iterate over the array until you run out of strings. Here is an example.

#include <stdio.h>

int main()
{
    char* names[] = {"John", "Paul", "George", "Ringo", '\0'};

    int size = 0;
    while(names[++size]!='\0');

    printf("Size: %d\n", size); // Prints "4"

    return 0;
}

This method has the advantage that it works even when the strings are of varying length. Note the terminating NULL byte in the names array, and the ; character to close the while statement as there is no statement body to run.

dotancohen
  • 30,064
  • 36
  • 138
  • 197
  • 3
    Would this only work well if there was a NULL as the last element of your *names[] array and if you're comparing against a NULL in the while loop? Otherwise you're banking on the memory where your strings are stored to be 'zeroed' which is not always the case! The above code is therefore not very safe or reliable. – mike Oct 14 '15 at 08:30
  • 2
    To add to the above, my understanding is that in the code above you're storing an array of pointers to strings. This array currently has 4 elements (i.e. 4 pointers to your strings). Each string is null terminated, but your array of pointers doesn't by default have a termination record - you need to manually set it, and `NULL` is a good candidate as the last record. This way you can easily recognise it in your `while` loop, by comparing against `NULL`. I hope my explanation is clear and my understanding correct. – mike Oct 14 '15 at 08:43
  • The last entry as `'\0'`, while *correct* in principle is not semantically clear. The last `'\0'` stands for a null pointer constant - it is better to use `NULL` or `0` there. – Antti Haapala -- Слава Україні Mar 23 '19 at 15:32
  • This is still wrong. Did you even try to compile it? You can't compare a character constant like `'\0'` with a pointer to a character. – jtchitty May 18 '21 at 03:57
-7

Making the Array Of Strings to run in a While loop with an Increment Operator, Until the loop becomes NULL, gives the Array Size:

#include<stdio.h>
char* names[]={"A", "B", "C"};

int main(){
int nameSize = 0;
while(names[++nameSize]!='\0');
}

for(i=0;i<nameSize;i++){
printf("%s\n", names[i]);
}

return 0;
}

Output:

A
B
C
Stephen King
  • 581
  • 5
  • 18
  • 31