-1

I need to count the length of a string in C without using the string.h library, using char pointers. So far all the methods I've seen use the string.h library. Is it possible to do it without i?

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 3
    Well, yes, `strlen` from `string.h` has to do it without other libraries. See also the [reference](https://en.cppreference.com/w/cpp/string/byte/strlen) that shows a possible implementation. – Lukas-T Dec 14 '20 at 11:17
  • 1
    Does this answer your question? [How to write a better strlen function?](https://stackoverflow.com/questions/6584340/how-to-write-a-better-strlen-function) – Mark Benningfield Dec 14 '20 at 12:09

3 Answers3

3

Yes it is possible, the end of a string in C is usually null terminated, so you can loop through the string until you find the '\0' character, counting each as you go.

0RR
  • 1,538
  • 10
  • 21
3

When talking about strings in C, you're essentially talking about an array of char, terminated by the nil character ('\0'). The length of a string, therefore is:

size_t len(const char *s) {
    // if no string was passed (null pointer), just return
    if (s == NULL)
        return 0;

    size_t ln;
    // iterate over string until you encounter the terminating char
    for (ln=0;s[ln] != '\0'; ln++);

    return ln;
}

As pointed out by @chux-ReinstateMonica: the correct type to return here is size_t, if you want to avoid potential overflow issues + you're looking for a drop-in replacement for the strlen() function in strings.h. The length of a string can, after all, never be negative, so using the unsigned size_t makes more sense than the signed int.

Now this obviously assumes the input was a valid string. If I were to do something like:

int main( void ) {
    char * random = malloc(1024); // allocate 1k chars, without initialising memory
    printf("length is: %zu\n", len(random)); // use %zu because size_t is unsigned!
    return 0;
}

There's no guarantee the memory I allocated will even contain a terminating character, and therefore it's not impossible for the function to return a value greater than 1024. Same goes for something like:

char foo[3] = {'f', 'o', 'o'}; // full array, no terminating char

This string, in memory, could look something like this:

//the string - random memory after the array
| f | o | o | g | a | r | b | a | g | e | U | B | \0 |

Making it look like a string of 12 characters. If you then use the assumed length of 12 to write past the actual array, all bets are off (undefined behaviour).

This string should've been:

char foo[4] = {'f', 'o', 'o', '\0'}; // or char[4] foo = "foo";

You can read an old answer I gave elsewhere for some more details on how to get the length of a string passed to a function here

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • 1
    Fails when string length exceeds `int` range. This `len()` does not match the return type of `strlen()`. Code like `printf("length is: %d\n", len(random));` needs more maintenance when switching between `len()` and `strlen()` to also adjust the print specifier. These issues solvable with using `size_t` than `int`. – chux - Reinstate Monica Dec 14 '20 at 16:03
  • @chux-ReinstateMonica: You're right, I believe I actually mention using `size_t` in the answer I linked at the bottom. Will update the code here, though – Elias Van Ootegem Dec 14 '20 at 16:40
1

Here example:

size_t pos(char* s)
{
    size_t lenS; //len of string

    for (lenS = 0; s[lenS]; lenS++);

    return lenS;
}
bogdyname
  • 358
  • 2
  • 10
  • Fails when string length exceeds `int` range. – chux - Reinstate Monica Dec 14 '20 at 16:01
  • 1
    @chux-ReinstateMonica: Doubt it matters. It's probably homework, and if it's not, it's just gotta be something embedded enough where a string exceeding int range is unreasonable. – Joshua Dec 14 '20 at 16:12
  • When `int` and `size_t` differ in size, printing the result of `len()` and `strlen()` then require different print specifiers even when the string length is 1. When coding for a strlen() replacement, makes most sense to use the same function signature. `size_t strlen(const char *s);` rather than change the type of the argument and return. – chux - Reinstate Monica Dec 14 '20 at 16:30