0

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?

2
  • 6
    I think it's pretty safe this way. But char *lastchar probably needs to be char lastchar, since you're indexing a single char in buf. I expect a compiler will warn you about that. Commented Sep 16, 2015 at 3:06
  • Unless buf is an empty string in which case strlen(buf) - 1 is -1, that's fine. Commented Sep 16, 2015 at 3:28

6 Answers 6

11

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];
Sign up to request clarification or add additional context in comments.

Comments

3

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)

Comments

1

Assuming your string is properly null terminated (as it is in your example) it's safe.

1 Comment

In C, a string is always properly null terminated, else it is not a string. A character array may exist that lacks null termination, but that is not a string.
0

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);

Comments

0

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.

1 Comment

The solution is worse than the problem.
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.