C: Custom strlen() library function

假装没事ソ 提交于 2019-12-11 00:09:09

问题


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 ??


回答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 type char, unsigned char, or signed 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.




回答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.




回答3:


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 function

Synopsis

    #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.




回答4:


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.




回答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;



回答6:


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;


来源:https://stackoverflow.com/questions/39438991/c-custom-strlen-library-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!