-1

I am trying to create strlen in C's standard library by myself like following, named it mystrlen. I added other parts to make it run. I used vim editor to write the code and gcc to run the code. The code had been successfully compiled.

#include <stdio.h>


int mystrlen(const char* str){
        int i;
        for (i=0;str[i]!='\n';i++);
        return i;
}

int main(void){
        char input[100];
        gets(input);
        printf("The length of your string : %d\n", mystrlen(input));
        return 0;
}

Then, I tried to run .exe file, when I input the abc, followings were displayed:

warning: this program uses gets(), which is unsafe.
abc
Segmentation fault: 11

I have also tested some other input strings and the result were the same.

When I input the aka, Segmentation fault: 11 didn't appeared and shows the length as 104.

warning: this program uses gets(), which is unsafe.
aka
The length of your string : 104

I have searched on the Internet about Segmentation fault: 11, but I couldn't find any similar situation with me. There seems to be memory access problems when Segmentation fault: 11 occurs, but I'm not sure where memory access failed.

Question
Could you please tell me how to improve this code to work as same as the strlen function in C's standard library?


Notation
During lots of trials by myself, I found strlen in C's standard library is unsigned long type, but I don't think this is the reason of Segmentation fault: 11 because no error regarding type appeared.

References
I wrote my code referred this link.

XYJ
  • 11
  • 5
  • 6
    The character `'\n'` is the newline. C strings are ***null*** terminated, with the character `'\0'`. You copy-pasted the linked code wrong. – Some programmer dude Dec 31 '22 at 08:44
  • 1
    And as the compiler tells you, never ***ever*** use the `gets` function! It's so [dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) it has even been removed from the C language. Use e.g. [`fgets`](https://en.cppreference.com/w/c/io/fgets) instead. – Some programmer dude Dec 31 '22 at 08:45
  • @Someprogrammerdude Thank you for your comment. After revising my code as you said, my code works well. – XYJ Dec 31 '22 at 08:47
  • 1
    Another nitpicking, GCC is the *compiler* that takes source code and creates an executable program. GCC doesn't "run" your code. – Some programmer dude Dec 31 '22 at 08:48
  • As for the "segmentation fault", it's a common crash when you use memory that doesn't belong to your program. Like for example going out of bounds of an array or using invalid pointers. What happens when you use newline is that you go out of bounds of the initialized memory of the array, and possibly far of into memory outside of the array. – Some programmer dude Dec 31 '22 at 08:52
  • @Haris Thank you for your comment. I have realized the reason why my code didn't worked well. Since I had set the end condition of for loop as ```str[i]=='\n'```, but ```'\n``` is not included in the input string, my program tried to access the element of ```str``` over its length. – XYJ Dec 31 '22 at 08:53
  • Thank you for your advice regarding ```gets```. I have searched about it and found that it is recommended to use ```fgets``` with designating the buffer size. Is this what you want to tell me? I appreciate if you give some comments. – XYJ Dec 31 '22 at 08:59
  • @Someprogrammerdude Thank you for your comment regarding ```GCC```. Just want to clarify, is it possible to ran the ```.exe``` code even without any compilers like GCC installed in my computer? – XYJ Dec 31 '22 at 09:02
  • Regarding `gets`, yes you should use `fgets` to not risk buffer overflows. There have been a lot of real-world exploits that used buffer overflow from `gets`. – Some programmer dude Dec 31 '22 at 09:05
  • Regarding GCC, it's not possible to create an executable program from C source without a compiler. It's the compiler (and linker) which creates the executable file that you can run. – Some programmer dude Dec 31 '22 at 09:06
  • @Someprogrammerdude I have seen the warning message regarding ```gets()``` for many times, but unsure of how to fix it. It was not until you told me that I have learned how to fix it. – XYJ Dec 31 '22 at 09:40
  • @Someprogrammerdude Thank you for your reply. Is it possible to run ```.exe``` files that were compiled on different computers on the computer without installing any compilers? – XYJ Dec 31 '22 at 09:44

2 Answers2

2

If you want to reimplement strlen you should return a size_t instead of an int and check for str[i] != '\0' instead of str[i] != '\n'

Pay attention to the warnings:

warning: this program uses gets(), which is unsafe.

gets is no longer part of the standard and it was unsafe because there is no way to prevent buffer overflows with it. Anyway, gets doesn't include the newline (that's why it segfaults reading beyond the limits of the array).

You must avoid this function and use fgets (or getline if available):

if (fgets(input, sizeof input, stdin))
{
    input[strcspn(input, "\n")] = '\0'; // Strip the trailing newline
    printf("The length of your string : %zu\n", mystrlen(input));  
} 
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • Thank you for your answer. I revised my code based on your answer and it worked well. – XYJ Dec 31 '22 at 09:49
  • Regarding the use of ```fgets```, I have search it and found [this link](https://www.educative.io/answers/how-to-use-the-fgets-function-in-c). It said that if there is an error or the end of file character is encountered, it will return ```NULL``` pointer. However, I wonder whether ```NULL``` pointer works well in ```if```. Does ```NULL``` pointer means ```int``` value of ? – XYJ Dec 31 '22 at 09:54
  • _Does NULL pointer means int value of ?_ A null pointer constant is an integer constant expression with the value 0. `if (fgets(input, sizeof input, stdin))` is equivalent to `if (fgets(input, sizeof input, stdin) != NULL)`. Check: [What is the difference between NULL, '\0' and 0?](https://stackoverflow.com/questions/1296843/what-is-the-difference-between-null-0-and-0) – David Ranieri Dec 31 '22 at 09:58
  • 1
    Thank you for your reply. I looked at the URL you gave and realized that ```0``` is another expression of ```NULL``` pointer. – XYJ Dec 31 '22 at 12:36
1

Your problem is the check on the new line character str[i] != '\n'. In C the NULL Terminator \0 determine the end of a string.

int mystrlen(const char* str){
        int i;
        for (i=0; str[i] != '\0'; i++);
        return i;
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
Maxwell D. Dorliea
  • 1,086
  • 1
  • 8
  • 20
  • Thank you for your answer. When I revised my code as you suggested, it worked well. – XYJ Dec 31 '22 at 09:38