Home > Software design >  Why am I getting a message segmentation fault?
Why am I getting a message segmentation fault?

Time:12-19

Using C, I am trying to implement a function that converts word into mutated_word according to the key string_word. eg: when word is "HE", with the key "QWERTYUIOPASDFGHJKLZXCVBNM", the mutated_word should become "IT". But it keeps giving segmentation fault, not sure how to improve.

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

int main(void) {
    string word = "HE" ;
    string string_word = "QWERTYUIOPASDFGHJKLZXCVBNM";
    char mutated_word[strlen(word)]; 
    
    for (int i = 0; word[i] != '\0'; i  ) {
        string_word[(int)word[i] - 65] = mutated_word[i];
    }
    
    printf("%s", mutated_word);
}

CodePudding user response:

  1. You need to terminate the new string with null character.
  2. Your array is too small
  3. Use the correct type for indexes (int is not the correct one)
  4. Check if the character is the letter. If not decide what to do (in my example I convert all letters to uppercase, other chars are left as they are)
  5. Do not use magic numbers. Instead of 65 use 'A'
  6. Your assignment is wrong, you actually want something right opposite.
  7. It will not work with all character encoding.
#include <ctype.h>
#include <stdio.h>

int main (void) 
{
    string word = "HE" ;
    string string_word = "QWERTYUIOPASDFGHJKLZXCVBNM" ;
    char mutated_word [strlen(word)   1]; 
    
    size_t i;
    for (i = 0; word[i] != '\0'; i  )
    {
        if(isalpha((unsigned char)word[i]))
        {
            mutated_word[i] = string_word[toupper((unsigned char)word[i]) - 'A'];
        }
        else
        {
            mutated_word[i] = word[i];
        }
    }
    mutated_word[i] = 0;
   
    printf("%s", mutated_word); 
}

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

To make it more portable:

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>

ptrdiff_t findIndex(const char ch, const char * restrict dict)
{
    char *result = strchr(dict, ch);
    if(!result) return -1;
    return result - dict;
}

int main (void) 
{
    string word = "He124" ;
    string string_word = "QWERTYUIOPASDFGHJKLZXCVBNM" ;
    string dict = "ABCDEFGHIJKLMNOPQRSTUVXYWZ";
    ptrdiff_t index;
    char mutated_word [strlen(word)   1]; 
    
    size_t i;
    for (i = 0; word[i] != '\0'; i  )
    {
        if(isalpha((unsigned char)word[i]))
        {
            index = findIndex(toupper((unsigned char)word[i]), dict);
        }
        else index = -1;
        mutated_word[i] = index == -1 ? word[i] : string_word[index];

    }
    mutated_word[i] = 0;
   
    printf("%s", mutated_word); 
}

https://godbolt.org/z/KW8TxxEvq

CodePudding user response:

You program crashes because the assignment is in the wrong order: string_word[(int)word[i] - 65] = mutated_word[i]; is attempting to modify a string literal, which has undefined behavior. Note also that the destination string must be 1 byte longer for the null terminator, which you must set explicitly.

Here is a more portable version:

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

int main(void) {
    const char *word = "HE";
    const char *normal_word = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const char *string_word = "QWERTYUIOPASDFGHJKLZXCVBNM";
    char mutated_word[strlen(word)   1]; 
    unsigned char c;
    const char *p;
    size_t i;

    for (i = 0; (c = word[i]) != '\0'; i  ) {
        if ((p = strchr(normal_word, c)) != NULL) {
            c = string_word[p - normal_word];
        } else
        if ((p = strchr(normal_word, toupper(c))) != NULL) {
            c = string_word[p - normal_word];
            c = tolower(c);
        }
        mutated_word[i] = c;
    }
    mutated_word[i] = '\0';
   
    printf("%s\n", mutated_word); 
    return 0;
}

CodePudding user response:

it's because you exceeded the size of string_word[] note that per example 'Z'-65 == 25 which is bigger than (int)strlen(string_word)

  •  Tags:  
  • c
  • Related