Home > Mobile >  Core Dump (Segmentation fault) in this little encryption program I wrote in C for cs50
Core Dump (Segmentation fault) in this little encryption program I wrote in C for cs50

Time:09-13

The error happens after the user enters the plaintext. I'm quite new to this language and programming itself. Help would be greatly appreciated. Since I am working in the cs50 codespace I cant use the debugger for some reason and cant see the code dump as one other question suggested I can solve the issue myself. Been at this for a few days and had to post a question now. Thanks.

 bool no_repeat(string key, int l);
string cipher(string key, string input, int l);

int main(int argc, string argv[])
{

    if (argc == 2)
    {
        string key = argv[1];
        int l = strlen(key);
        int ver = 0;
        for (int i = 0; i < l; i  )
        {
            if (isalpha(key[i]))
            {
                ver  ;
            }
        }
        bool c = no_repeat(key, l);
    if (strlen(argv[1]) == 0)
    {
        printf("Please enter an encryption key.\n");
        return 1;
    }
else if ((l != 26) || (ver != 26) || (c == false))
    {
        printf("Please input a correct encryption key.\n");
        return 1;
    }
}
else if (argc == 1)
{
    printf("Please enter an encryption key.\n");
    return 1;
}
string key = argv[1];
int l = strlen(key);
string input = get_string("plaintext:");
string cipherText = cipher(key, input, l);
printf("ciphertext: %s\n", cipherText);
return 0;

}


bool no_repeat(string key, int l)
{
    for(int i = 0; i < l; i  )
    {
        for (int k = i 1; k < l; k  )
        {
            if (key[i] == key[k])
            {
                return false;
            }
        }
    }
    return true;
}

string cipher(string key, string input, int l)
{
    string output = "";
    string alphabets = "abcdefghijklmnopqrstuvwxyz";
    for(int i = 0 ; i < l ; i  )
    {
        int isUpper = isupper(key[i]);
        key[i] = tolower(key[i]);
        for (int k = i ; k < l ; k  )
        {
            if (input[i] == alphabets[k])
            {
                output[i] = key[k];
            }
            else

                {
                    output[i] = input[i];
                }
            }
            if (isUpper != 0)
            {
                output[i] = toupper(output[i]);
            }
        }
        return output;
    }

CodePudding user response:

string is probably a typedef char * string; and in that case you cannot modify string output = "";. Instead you want to use malloc() to allocate a string sufficiently large, i.e.:

string output = malloc(strlen(input)   1);
if(!output) {
  printf("malloc failed\n");
  exit(1);
}

In cipher() you were also doing input[i] but i goes from 0 to strlen(key) so you will likely result in out of bound access. For me, cipher() was returning the input for ciphertext. Here is the fixed version (note, removed the argument l here and from caller as it's not needed):

string cipher(string key, string input) {
    string output = malloc(strlen(input)   1);
    if(!output) {
        printf("malloc failed\n");
        exit(1);
    }
    const string alphabet = "abcdefghijklmnopqrstuvwxyz";
    size_t j = 0;
    for(size_t i = 0; i < strlen(input); i  , j  ) {
        string pos = strchr(alphabet, tolower(input[i]));
        if(!pos) {
            printf("letter %c not found in alphabet\n", input[i]);
            exit(1);
        }
        output[j] = key[pos - alphabet];
    }
    output[j] = '\0';
    return output;
}

and example execution:

~$ ./a.out abcdefghijklmnopqrtsuvwxzy # swap s and t
plaintext:test
ciphertext: sets

You don't have to store the alphabet, btw, as in ASCII pos - alphabet is the same value as tolower(input[i]) - 'a'.

  • Related