Segfault when re-implementing tolower() in C

43 views Asked by At

The aim was to create a function that could convert all characters into lowercase to avoid caps sensitivity when asking a question, similar to that of .lower() in python. Currently the code below will come out with a "zsh: segmentation fault"

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

void lower(char *s[]){
    int length = sizeof(*s)/sizeof(*s[0]);
    int i;

    for(i = 0; i < length; i++){
        if (*s[i] >= 'A' && *s[i] <= 'Z'){
            s[i] += 32;
        }
    }
    printf("%s",*s);
}

int main(){
    char *variable[40];
    printf("what would you like to do: ");
    fgets(*variable, sizeof(*variable),stdin);
    lower(variable);
    printf("%s", *variable);
    return 0;

}

I have tried int length = sizeof(*s)/sizeof(*s[0]); and other methods of changing the length, including using a plain number, the same length assigned to the character length. How can I fix this?

Thank you.

P.S I don't want to use a pre-made function for this, as I want to better understand C and implement the function instead. Sorry for being difficult.

1

There are 1 answers

4
gulpr On BEST ANSWER

Many issues:

  1. char *variable[40]; - it is an array of 40 pointers to char. Those pointers are not initialized. When you dereference any of them, you invoke undefined behaviour. You want an array of char
  2. int length = sizeof(*s)/sizeof(*s[0]); it does not work in this scope. You will divide the size of pointer by size of pointer and you most likely will get 1. You want to use strlen. Also s needs to be pointer to char
void lower(char *s){
    size_t length = strlen(s);
    for(size_t i = 0; i < length; i++){
        if (s[i] >= 'A' && s[i] <= 'Z'){
            s[i] += 'a' - 'A';
        }
    }
    printf("'%s'\n",s);
}

int main(){
    char variable[40];
    printf("what would you like to do: ");
    fgets(variable, sizeof(variable),stdin);
    lower(variable);
    printf("`%s`\n", variable);
}

https://godbolt.org/z/4s4r7ffn1

But it is much better to use tolower function:

void lower(char *s){
    size_t length = strlen(s);
    for(size_t i = 0; i < length; i++)
        s[i] = tolower(s[i]);
    printf("'%s'\n",s);
}