Reputation: 303
i know two way's to get length of const char *
const char * str = "Hello World !";
int Size = 0;
while (str[Size] != '\0') Size++;
and other way is very simple
const char * str = "Hello World !";
size_t Size = strlen(str);
but i don't want to use str lib functions like strlen
and i think this function use my first way behavior too. because in the pc world when we want to count something we need to count each block's and there is no magic to get the length with one movement so i think the first way is the best option to get length of const char *
. other way i think the first way is maybe too heavy for heavy string's. so im confused. which way is better and why other way is not ?
Upvotes: 26
Views: 87104
Reputation: 70
3 years late but better late that never.
#define length(array) ((sizeof(array)) / (sizeof(array[0])))
So using sizeof(array)
returns the size of the type of the array
* the amount of elements
. Knowing this, we could achieve this:
#define length(array) ((sizeof(array)) / (sizeof(array[0])))
and you would use it like:
type yourArray[] = {your, values};
length(yourArray); // returns length of yourArray
For example:
#include <stdlib.h>
#include <stdio.h>
#define length(array) ((sizeof(array)) / (sizeof(array[0])))
int main()
{
const char *myStrings[] = {"Foo", "Bar", "Hello, World!"}; // 3 elements
int myNums[] = {0, 1, 5, 7, 11037}; // 5 elements
char myChars[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; // 7 elements
printf("Length of myStrings array: %lu\n", length(myStrings));
printf("Length of myNums array: %lu\n", length(myNums));
printf("Length of myChars array: %lu\n", length(myChars));
return 0;
/* Output:
Length of myStrings array: 3
Length of myNums array: 5
Length of myChars array: 7 */
}
I tested it and it also works with uninitialized arrays, probably because they contain garbage (from being uninitialized) from the same type. Integer uninitialized arrays contain random integer numbers and const char* uninitialized arrays contain (null) which is treated as a const char*.
Now, this only works with arrays on the stack. Pointers pointing to space reserved in the heap used as an array would give unexpected results. For example:
int *myNums = (int *)malloc(3 * sizeof(int)); // Space for 3 integers
printf("Length of myNums: %lu\n", length(myNums)); // Outputs 2 instead of 3
So be advised. Who uses arrays on the heap anyways so whatever.
Note: This is relevant to this question as it works with const char * as requested. Works with other types too.
Upvotes: 3
Reputation:
Let's inspect the assembly listing of these two methods.
#include <cstddef>
#include <cstring>
int string_size_1()
{
const char * str = "Hello World !";
int Size = 0;
while (str[Size] != '\0') Size++;
return Size;
}
int string_size_2()
{
const char * str = "Hello World !";
size_t Size = strlen(str);
return Size;
}
Using Clang 4.0.0 with flags -std=c++14 -O2
string_size_1(): # @string_size_1()
mov eax, 13
ret
string_size_2(): # @string_size_2()
mov eax, 13
ret
Link: https://godbolt.org/g/5S6VSZ
Both methods end up with exactly the same assembly listing. Also, the compiler optimizes away everything and just return a constant because the string literal is known during compile-time. So, in terms of performance, they are equally good.
But in terms of readability, strlen(str)
is definitely better. A function call states the intention through the function name. A loop cannot do that.
Besides, std::string
and std::string_view
are more preferable than C-string in many cases. Consider them.
Upvotes: 40
Reputation: 105
In this case the answer is known at compile time:
template <std::size_t S>
constexpr std::size_t string_length
(
char const (&)[S]
)
{
return S - 1;
}
usage:
std::cout << string_length("example") << std::endl;
For cases where the string is not a compile time constant use strlen if only the pointer to the string is available, std::distance if both pointers to the beginning and end are available, or .size() if your dealing with a std::string
Upvotes: 3