TransWikia.com

Why does this C code give me a segmentation fault?

Stack Overflow Asked by Deegan on December 18, 2021

Using the CS50 library, this is my code but it keeps giving me a segmentation fault. I have tried to figure out where it keeps doing a segmentation fault, and for some reason it has to do with my function. Why does it keep doing this?

#import <cs50.h>
#import <stdio.h>
#import <ctype.h>
#import <string.h>

string ciphertext(string plaintext[1], string key[1]);

int main(int argc, string argv[])
{
    // Variables
    string plaintext2[1];

    if (argc == 2)
    {
        if(strlen(argv[1]) == 26)
        {
            string text = get_string("plaintext: ");
            plaintext2[0] = text;
        }
        else
        {
            printf("Key must contain 26 characters.n");
            return 1;
        }
    }
    else
    {
        printf("Usage: ./substitution keyn");
        return 1;
    }

    string ciphertext2 = ciphertext(&plaintext2[0], &argv[1]);
    printf("ciphertext: %sn", ciphertext2);
}

string ciphertext(string plaintext[1], string key[1])
{
    // Variables
    string ciphertext[1];

    for (int i = 0; i < strlen(plaintext[0]); i++)
    {
        if (plaintext[0][i] == 'a')
        {
            ciphertext[0][i] = tolower(key[0][0]);
        }
        else if (plaintext[0][i] == 'A')
        {
            ciphertext[0][i] = toupper(key[0][0]);
        }
        else if (plaintext[0][i] == 'b')
        {
            ciphertext[0][i] = tolower(key[0][1]);
        }
        else if (plaintext[0][i] == 'B')
        {
            ciphertext[0][i] = toupper(key[0][1]);
        }
        else if (plaintext[0][i] == 'c')
        {
            ciphertext[0][i] = tolower(key[0][2]);
        }
        else if (plaintext[0][i] == 'C')
        {
            ciphertext[0][i] = toupper(key[0][2]);
        }
        else if (plaintext[0][i] == 'd')
        {
            ciphertext[0][i] = tolower(key[0][3]);
        }
        else if (plaintext[0][i] == 'D')
        {
            ciphertext[0][i] = toupper(key[0][3]);
        }
        else if (plaintext[0][i] == 'e')
        {
            ciphertext[0][i] = tolower(key[0][4]);
        }
        else if (plaintext[0][i] == 'E')
        {
            ciphertext[0][i] = toupper(key[0][4]);
        }
        else if (plaintext[0][i] == 'f')
        {
            ciphertext[0][i] = tolower(key[0][5]);
        }
        else if (plaintext[0][i] == 'F')
        {
            ciphertext[0][i] = toupper(key[0][5]);
        }
        else if (plaintext[0][i] == 'g')
        {
            ciphertext[0][i] = tolower(key[0][6]);
        }
        else if (plaintext[0][i] == 'G')
        {
            ciphertext[0][i] = toupper(key[0][6]);
        }
        else if (plaintext[0][i] == 'h')
        {
            ciphertext[0][i] = tolower(key[0][7]);
        }
        else if (plaintext[0][i] == 'H')
        {
            ciphertext[0][i] = toupper(key[0][7]);
        }
        else if (plaintext[0][i] == 'i')
        {
            ciphertext[0][i] = tolower(key[0][8]);
        }
        else if (plaintext[0][i] == 'I')
        {
            ciphertext[0][i] = toupper(key[0][8]);
        }
        else if (plaintext[0][i] == 'j')
        {
            ciphertext[0][i] = tolower(key[0][9]);
        }
        else if (plaintext[0][i] == 'J')
        {
            ciphertext[0][i] = toupper(key[0][9]);
        }
        else if (plaintext[0][i] == 'k')
        {
            ciphertext[0][i] = tolower(key[0][10]);
        }
        else if (plaintext[0][i] == 'K')
        {
            ciphertext[0][i] = toupper(key[0][10]);
        }
        else if (plaintext[0][i] == 'l')
        {
            ciphertext[0][i] = tolower(key[0][11]);
        }
        else if (plaintext[0][i] == 'L')
        {
            ciphertext[0][i] = toupper(key[0][11]);
        }
        else if (plaintext[0][i] == 'm')
        {
            ciphertext[0][i] = tolower(key[0][12]);
        }
        else if (plaintext[0][i] == 'M')
        {
            ciphertext[0][i] = toupper(key[0][12]);
        }
        else if (plaintext[0][i] == 'n')
        {
            ciphertext[0][i] = tolower(key[0][13]);
        }
        else if (plaintext[0][i] == 'N')
        {
            ciphertext[0][i] = toupper(key[0][13]);
        }
        else if (plaintext[0][i] == 'o')
        {
            ciphertext[0][i] = tolower(key[0][14]);
        }
        else if (plaintext[0][i] == 'O')
        {
            ciphertext[0][i] = toupper(key[0][14]);
        }
        else if (plaintext[0][i] == 'p')
        {
            ciphertext[0][i] = tolower(key[0][15]);
        }
        else if (plaintext[0][i] == 'P')
        {
            ciphertext[0][i] = toupper(key[0][15]);
        }
        else if (plaintext[0][i] == 'q')
        {
            ciphertext[0][i] = tolower(key[0][16]);
        }
        else if (plaintext[0][i] == 'Q')
        {
            ciphertext[0][i] = toupper(key[0][16]);
        }
        else if (plaintext[0][i] == 'r')
        {
            ciphertext[0][i] = tolower(key[0][17]);
        }
        else if (plaintext[0][i] == 'R')
        {
            ciphertext[0][i] = toupper(key[0][17]);
        }
        else if (plaintext[0][i] == 's')
        {
            ciphertext[0][i] = tolower(key[0][18]);
        }
        else if (plaintext[0][i] == 'S')
        {
            ciphertext[0][i] = toupper(key[0][18]);
        }
        else if (plaintext[0][i] == 't')
        {
            ciphertext[0][i] = tolower(key[0][19]);
        }
        else if (plaintext[0][i] == 'T')
        {
            ciphertext[0][i] = toupper(key[0][19]);
        }
        else if (plaintext[0][i] == 'u')
        {
            ciphertext[0][i] = tolower(key[0][20]);
        }
        else if (plaintext[0][i] == 'U')
        {
            ciphertext[0][i] = toupper(key[0][20]);
        }
        else if (plaintext[0][i] == 'v')
        {
            ciphertext[0][i] = tolower(key[0][21]);
        }
        else if (plaintext[0][i] == 'V')
        {
            ciphertext[0][i] = toupper(key[0][21]);
        }
        else if (plaintext[0][i] == 'w')
        {
            ciphertext[0][i] = tolower(key[0][22]);
        }
        else if (plaintext[0][i] == 'W')
        {
            ciphertext[0][i] = toupper(key[0][22]);
        }
        else if (plaintext[0][i] == 'x')
        {
            ciphertext[0][i] = tolower(key[0][23]);
        }
        else if (plaintext[0][i] == 'X')
        {
            ciphertext[0][i] = toupper(key[0][23]);
        }
        else if (plaintext[0][i] == 'y')
        {
            ciphertext[0][i] = tolower(key[0][24]);
        }
        else if (plaintext[0][i] == 'Y')
        {
            ciphertext[0][i] = toupper(key[0][24]);
        }
        else if (plaintext[0][i] == 'z')
        {
            ciphertext[0][i] = tolower(key[0][25]);
        }
        else if (plaintext[0][i] == 'Z')
        {
            ciphertext[0][i] = toupper(key[0][25]);
        }
        else
        {
            ciphertext[0][i] = plaintext[0][i];
        }
    }
    return ciphertext[0];
}

I really need some help, and I don’t know why it keeps giving a fault.

2 Answers

You already have the answer (@Vlad from Moscow), but I would like to point out a few things:

  1. Duplicating is a very bad practice, it is unreadable and more important seriously time-consuming. If you see "100" else if() statements one below the other you should suspect that something is terribly wrong with your code.

  2. Try your best to avoid using numbers in your code. What if you want to change a value that you already copy-pasted a hundred times? Instead of using numbers, I would advise you to use variables and symbolic constants

Try to improve your current code, you can write something like this:

for (int i = 0; i < strlen(plaintext[0]); i++)
{
    int ind = 0;
    int lower_case = 97, upper_case = 65;
    
    if (plaintext[0][i] == lower_case)
    {
        ciphertext[0][i] = tolower(key[0][ind]);
    }
    else if (plaintext[0][i] == upper_case)
    {
        ciphertext[0][i] = toupper(key[0][ind]);
    }
    
    ind++; lower_case++; upper_case++;
}

Answered by Majkl on December 18, 2021

The array

string ciphertext[1];

is uninitialized and has indeterminate value.

Accessing such an array the way like this

ciphertext[0][i] = tolower(key[0][0]);

results in undefined behavior.

You need to allocate a character array with the size equal to the value of the expression

strlen( *plaintext ) + 1

Pay attention to that instead the numerous if-else statement you could define a string literal like for example

string letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

and then you can use the standard string function strchr like

char *p = strchr( letters, toupper( ( unsigned char)plaintext[0][i] ) );
if ( p != NULL )
{
    if ( plaintext[0][i] == *p )
    {
        ciphertext[0][i] = key[0][p - letters]);
    }
    else
    {
        ciphertext[0][i] = tolower(key[0][p - letters]);
    }
}

Answered by Vlad from Moscow on December 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP