strlen usually works by counting the characters in a string until a \0 character is found. A canonical implementation would be:
size_t strlen (char *str) {
size_t len = 0;
while (*str != '\0') {
str++;
len++;
}
return len;
}
As for possible inherent bugs in the function, there are none - it works exactly as documented. That's not to say it doesn't have certain problems, to wit:
- if you pass it a "string" that doesn't have a
\0at the end, you may run into problems but technically, that's not a C string (a) and it's your own fault. - you can't put
\0characters within your string but, again, it wouldn't be a C string in that case. - it's not the most efficient way - you could store a length up front so you could get the length much quicker.
But none of these are bugs, they're just consequences of a design decision.
On that last bullet point, see also this excellent article by Joel Spolsky where he discusses various string formats and their characteristics, including normal C strings (with a terminator), Pascal strings (with a length) and the combination of the two, null terminated Pascal strings.
Though he has a more, shall we say, "colorful" term for that final type, one which frequently comes to mind whenever I thing of Python's excellent (and totally unrelated) f-strings :-)
(a) A C string is defined as a series of non-terminator characters (any character other than \0) followed by a terminator. Hence this definition disallows both embedded terminators within the sequence, and sequences without such a terminator. Or, putting it more succinctly (as per the ISO C standard):
Answer from paxdiablo on Stack OverflowA string is a contiguous sequence of characters terminated by and including the first null character.
c - How does the strlen function work internally? - Stack Overflow
I recently started coding with C, while using strlen function I get the exact number of length of string and sometimes not....in the below out len should be 3 but it's 4, why?
string - strlen function in c - Stack Overflow
Calculating length of a string with strlen()
Videos
include <stdio.h>
include<string.h>
int main()
{
char a[100];
printf("enter name:");
fgets(a,sizeof(a),stdin);
printf("len = %d",strlen(a));
}
output:
enter name:abc
len = 4
There's a good chance that you're doing this to a string that you have obtained with fgets or a similar input function. In that case, it may well have the newline at the end still.
If you change your code temporarily to:
void xyz (char *number) {
int i = 0, length = strlen (number);
while (i < length)
printf ("Number[%d]: %c (%d)", i, number[i], number[i]);
i++;
}
}
that should also show the numeric codes for all characters.
The problem with encoding something like that - 2 in your function is that it will not work with:
xyz ("123");
since it will stop early, printing out only 12. The caller should be calling with valid data, meaning that it should adjust the value to be a numeric string before calling.
You can see this happening in the following program:
#include <stdio.h>
#include <string.h>
void xyz (char *number) {
int i = 0, length = strlen(number) - 2;
while(i <= length)
{
printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
i++;
}
puts ("===");
}
void xyz2 (char *number) {
int i = 0, length = strlen(number);
while(i < length)
{
printf("Number[%d]: %c (%d)\n",i, number[i], number[i]);
i++;
}
puts ("===");
}
int main (void) {
char buff[100];
printf ("Enter number: ");
fgets (buff, sizeof (buff), stdin);
xyz (buff);
xyz ("12345");
xyz2 (buff);
xyz2 ("12345");
return 0;
}
The (annoted) output of this, if you enter 98765, is:
Enter number: 98765
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55) # Your adjustment works here because of the newline.
Number[3]: 6 (54)
Number[4]: 5 (53)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51) # But not here, since it skips last character.
Number[3]: 4 (52)
===
Number[0]: 9 (57)
Number[1]: 8 (56)
Number[2]: 7 (55) # Here you can see the newline (code 10).
Number[3]: 6 (54)
Number[4]: 5 (53)
Number[5]:
(10)
===
Number[0]: 1 (49)
Number[1]: 2 (50)
Number[2]: 3 (51) # And proper numeric strings work okay.
Number[3]: 4 (52)
Number[4]: 5 (53)
===
If you're looking for a robust user input function that gets around this problem (and avoids dangerous things like unbounded scanf("%s") and gets), I have one elsewhere on SO (right HERE, in fact) drawn from my arsenal.
Check if this works for you --
void xyz(char *number)
{
int length = strlen(number);
while(i < length)
{
printf("Number[]: %c",number[i]);
i++;
}
}
and this function, if invoked as
xyz("1234");
should print out:
Number[]: 1
Number[]: 2
Number[]: 3
Number[]: 4
Is that what you really wanted ? If so, then let me point 2 mistakes.
1) "i" is not initialized. It is more a question of good practise. Explicitly initialize your loop control variable (to zero in this case), just don't assume it to be set. 2) your while loop condition with "<=" runs 1 extra cycle that it should.
Remember that arrays start from index '0' (zero), and an array of size 10, has valid index from 0 to 9, and C lang uses null character ('\0'), to terminate a string. So, your "1234" is actually stored as:-
string[0] = '1' string[1] = '2' string[2] = '3' string[3] = '4' string[4] = '\0' (<= NULL)
so if your loop-counter (control variable) i=0 at beginning of loop, for first iteration, you pick string[0], and for 2nd iteration (when i=1) you pick string[1]... and this way, the loop should run only 4 times, i.e. when i==4 (i.e. loopcounter < string-length), you must stop & exit loop.
Hope this clears up your doubt and help. If so, please don't forget to accept the answer.
Let's say that we have a string char myStr[] = "Hello there!"
The 1st option to calculate the length is
int length = sizeof(myStr)/ sizeof(myStr[0]);
The 2nd option is simply to use the strlen() function, but I'm seeing that it will not count the null terminating character at the end.
My question: Would it be a problem using strlen() in embedded projects since it dosn't include the null terminating character as it's length? Or it's safer to just use the 1st option instead?
I'm thinking as an example of a case when you need to allocate emory, and you're relying on this strlen() function, it will not allocate for the null character, which might lead to problems down the line?
Thanks