'C: Custom strlen() library function
I created my version of strlen()
function.
unsigned int my_strlen(char *p)
{
unsigned int i = 0;
while(*p!='\0')
{
i++;
p++;
}
return i;
}
It gives me correct output everytime i run.But my collegues are saying this code may cause problem on systems where length of character is greater than 1 byte
. Is that so ??
So they modified the code as following:
unsigned int my_strlen(char *p)
{
unsigned int i = 0;
char *start = p;
while(*p!='\0')
{
i++;
p++;
}
return p - start;
}
I always thought in C a character is 1 byte long.
Is former snippet is better than the latter or vice versa ??
Solution 1:[1]
It is guaranteed in C that sizeof(char)
is 1, so you are right.
To add some authenticity, directly quoting C11
, chapter ยง6.5.3.4, The sizeof
and _Alignof
operators
When
sizeof
is applied to an operand that has typechar
,unsigned char
, orsigned char
, (or a qualified version thereof) the result is 1. [....]
That said, pointer arithmetic honors the data type, so the second approach does not make any sense in the respect of what is is expected to do, anyway. Both the case, you're operating on p
, which is char*
, so the effect will be the same.
Solution 2:[2]
As you use p++
, you increment you pointer by sizeof(char)
. Hence, it's not relevant what is sizeof(char)
even if it was variable between different machines. Your colleagues are wrong.
Note: If you want to count the bytes, and not the characters, then your colleagues could be correct (if char was not guaranteed to be 1 byte, but it is). If you want to count the characters, then your colleagues are just wrong at all.
Solution 3:[3]
OP posted "length of character is greater than 1 byte", not char
. OP is right when one limits a character to only char
, signed char
, unsigned char
. Those 3 always have a size of 1.
OP's colleagues may not all think in that restrictive sense. The C spec has many character types: single-byte character, multibyte character, extended character, wide character, not all 1 byte.
Modified code has weakness. It does not sensible relate to "length of character is greater than 1 byte". Also, the i++;
is pointless. The return type of unsigned
maybe insufficient. Use size_t
for an unsigned type that is neither too wide nor narrow.
// simplify
size_t my_strlen2(const char *p) {
const char *start = p;
while(*p) p++;
return (size_t) (p - start);
}
Is former snippet is better than the latter or vice versa ??
Neither returns a type that will not overflow.
Solution 4:[4]
Although the others answered your question regarding the character size, your version is still not correct.
The current standard (ISO/IEC 9899:2011) is short and precise here:
7.24.6.3 The
strlen
functionSynopsis
#include <string.h>`<br> size_t strlen(const char *s);
Description
2 The
strlen
function computes the length of the string pointed to by s.Returns
3 The
strlen
function returns the number of characters that precede the terminating null character.
So a fully compliant function would be
size_t stringlength(const char *s){
size_t i = 0;
while(s && *s != '\0'){
s++;
i++;
}
return i;
}
The main difference is that it checks the input (could be NULL
, but e.g.: glibc's strlen
segfaults. If you want it to segfault, strip the test for s == NULL
in the loop. Segfaulting is probably the better alternative, otherwise you get the sort of bugs we like to call "Heisenbugs". Bugs that tend to disappear when you look at them and their waveform collapses) and uses size_t
as the output.
The Glibc version handles several bytes at once if and when possible--don't know if such an optimization is useful.
If you want the equivalent of wsclen()
you can do something like that:
#include <wchar.h>
size_t wstringlength(const wchar_t *s){
size_t i = 0;
while(s[i] != L'\0'){
i++;
}
return i;
}
Counting multibyte characters (mbrlen()
checks for one character only, but you can use mbrtowc()
) is quite complicated and out of the scope of this short post.
Solution 5:[5]
strlen
function using for
:
size_t my_strlen(const char *s) {
size_t n;
for (n = 0; *s; s++)
n++;
return n;
}
Or:
size_t n;
for (n = 0; *s != '\0'; s++)
n++;
return n;
Or:
size_t n;
for (n = 0; *(s++); )
n++;
return n;
Or:
size_t n;
for (n = 0; *s; n++)
s++;
return n;
Or:
size_t n = 0;
int i;
for (i = 0; s[i]; i++)
n++;
return n;
Solution 6:[6]
I think this is quite nice too.
unsigned int StrLen(const char* String)
{
unsigned int Counter;
for (Counter = 0; String[Counter] != '\0'; Counter++);
return Counter;
}
It just makes a loop until the counter reaches the null character, and increments the counter.
Solution 7:[7]
In terms of Pointer arithmetic, It is not going to give you different result on platform having char as 2 bytes long as you are working on pointers and pointer arithmetic always stick to data types. Here is another way of finding string len, which do not use pointer airthmetic-
int len = -1;
while(p[++len] != '\0');
return len;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | SomethingSomething |
Solution 3 | |
Solution 4 | deamentiaemundi |
Solution 5 | |
Solution 6 | triangleBoi |
Solution 7 |