Reputation: 9264
Is there a way for me to get the last char in a string with strlen? If not, I can't understand in what context strlen can be used.
char buf[256] = "Hello";
char * lastchar = buf[strlen(buf) - 1];
Is it safe to use it?
Upvotes: 0
Views: 10290
Reputation: 549
If the buffer contains guaranteed a 0 character and at least one character, it is safe. But this condition may not met ... in development phase, on errors in other software modules (which determines the buffer), in attack of a virus, .... Access on the position [-1] if the string es empty is usual not a problem in C language but it returns a non determined result. Hence this construct is too simple and usafe. In generally strlen is unsafe: Think on a situation, the software is not ready, the buffer is not filled because this part of software has an error, and the buffer contains ..AA AA.. (for example) till end of memory. Then the strlen(..) runs a long time, maybe crash on its end (because null-Pointer or memory protection) and may violate the cycle time of an interrupt. There are some better solutions, but not really standardized. My solution you can find in www.vishia.org/emc/html/Base/StringJc_en.html resp. the whole system www.vishia.org/emc
Upvotes: 0
Reputation: 488
strlen is unsafe for null pointers.
char* str = (char*)NULL;
size_t len = strlen(str); /* segmentation fault -- crash */
50 years later, this is still there, waiting to trap the unwary.
Fortunately , there is an easy remedy.
#define strlen(S) ( (S==NULL) ? 0 : strlen(S) )
will stop the seg fault and return 0 as expected.
Upvotes: 0
Reputation: 154169
The last char
in a string is always a null character.
char lastchar = buf[strlen(buf)];
A
string
is a contiguous sequence of characters terminated by and including the first null character. C11 §7.1.1
To get the second to last character in a string is safe only when the string contains more than the null character.
size_t len = strlen(buf);
if (len > 0) {
char secondtolastchar = buf[len-1];
}
Keep in mind strlen(buf) - 1
is never negative even if strlen()
returns zero. What happens below?
char buf2[2] = "X";
char *buf = &buf2[1];
char ch = buf[strlen(buf) - 1];
buf
takes on the address of the null character in buf2[]
and strlen(buf)
--> 0. So it looks like the next line of code would do buf[-1]
which hopefully would be 'X'
. Instead, strlen()
returns type size_t
which is some unsigned integer type. The subtraction of size_t
and int
certainly results in a size_t
. So ((size_t) 0) - 1
is the largest size_t
value:SIZE_MAX
and not -1. Thus buf[SIZE_MAX]
is outside the range of buf2[]
and is undefined behavior.
Therefore for safety, any subtraction like - 1
needs to consider the effect of overflow. The above code solves that with if (len > 0)
Upvotes: 3
Reputation: 5325
Provided your strings are actually null-terminated (otherwise they're not actually strings!!!), yes, it is safe, so long as there is at least one character (other than the terminating null) in the string.
strlen()
calculates the number of bytes in a null-terminated string, excluding the null terminator. Bear in mind that C uses 0-based indexing.
So "Hello"
is really 'H', 'e', 'l', 'l', 'o', '\0'
, strlen("Hello")
returns 5
, and so you are accessing buf[4]
(the 'o'
), which is fine. If you had the empty string, ""
, there is no second last character and so here it is important to check the return value of strlen()
before using it.
One caveat: If you meant to get the last character, you should have done
char lastchar = buf[strlen(buf) - 1];
and if you meant to get a pointer to the last character, you should have done
char * lastchar = &buf[strlen(buf) - 1];
Upvotes: 11
Reputation: 114488
Yes. That is one perfectly valid use, except you have to do pointer arithmetic instead of indexing: char * lastchar = buf + strlen(buf) - 1;
(remember that buf
is a pointer). An alternative would be to use strchr()
, which may be faster: char * lastchar = strchr(buf, '\0');
.
Another use of strlen()
can be when you want to copy a string and you need to know how much memory to allocate:
char *copy = malloc(strlen(buf) + 1);
strcpy(copy, buf);
Upvotes: 0
Reputation: 3779
Assuming your string is properly null terminated (as it is in your example) it's safe.
Upvotes: 1