0

I've been struggling with Vigenere for a while now, and now that I "believe" I got to the point, I get a segmentation fault error when I run the program. Weird thing is that while I try to spot the issue with Debug50, the tool doesn't return this error and actually allows me to run the program until the end... but it still gives a wrong result ^^

Would you be able to spot the bug that causes the segmentation fault ?

Thanks a lot!

Here's my code :

int main(int argc, string argv[])
{
    if (argc == 2 && isalpha(argv[1]))
    {
    char *k = argv[1];
        string p = get_string("plaintext: ");

        for (int i = 0, n = strlen(p); i < n; i++)
        {
            for (int j = 0, o = strlen(k); j < o; j++)
            {
                if (isupper(p[i]))
                {
                    printf("%c",(((int)p[i] + (k[j] % o)) - 65) % 26 + 'A');
                }
                else if (islower(p[i]))
                {
                    printf("%c",(((int)p[i] + (k[j] % o)) - 97) % 26 + 'a');
                }
                else
                {
                    printf("%c", p[i]);
                }
            }
        }
            printf("ciphertext: %s\n", p);
            return 0;

    }
    else
    {
        printf("Usage: ./vigenere k\n");
        return 1;
    }
}

1 Answer 1

0

Clearly a kind of Heisenbug.

gdb injects code into your programme, and maybe this code covers your mistake.

I don't exactly know the line where your segmentation fault happens (there simply is no obvious mistake for this kind of error), but I see a few flaws.

It begins with isalpha(argv[1]). isalpha expects a char, you supply a char*. This is where I guess the segmentation fault happens, though I have no idea why. You need a loop to test all the argv[1][i] individually. If any is non-alphabetic, print some usage instruction and exit. Your code including this faulty line should not compile without warnings.

You would have to print "ciphertext: " before printing any encrypted character. The printf("ciphertext: %s\n", p); at the end would make sense only if you stored the encrypted letters back in p instead of printing them instantly.

Your nested loops don't work like you would want them to. You should move linearly over the plaintext, and increment the position in the key whenever you encrypt a letter. There's two indices, but no second dimension, as there's only one valid value of j for a given i. But since it depends on the whole history, one cannot calculate one from the other. Nested loops are great for things like mario in pset1, where you have rows, and in these rows have individual characters.

k[j] % o makes no sense either, you might have meant something like k[j % o]. But even then, you need to make sure to ignore the case (for example by applying tolower or toupper to the key's character), and to transform the letters into shifts to apply.

1
  • Thanks Blauelf! I've resolved the argv[1] issue apparently. Now working on the whole encryption piece reading through your advice. Good luck to me ^^
    – Phil
    Commented Apr 20, 2018 at 14:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .