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:
- You need to terminate the new string with null character.
- Your array is too small
- Use the correct type for indexes (
int
is not the correct one) - 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)
- Do not use magic numbers. Instead of
65
use'A'
- Your assignment is wrong, you actually want something right opposite.
- 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)