0

I have tried everything and I've been with this for one and a half months. what is the problem? When I run it, it outputs some characters correctly, but others not. I think the problem is with the looping because that is when it failed.

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

int main (int argc, string argv[])
{
    //Getting user imput
    string keyword = argv[1];
    string plaintext = GetString();

    //Validating the user imput
    if (argc < 2)
       return 1;

    int b = strlen(keyword);
    for (int a = 0; a < b; a++)
    {
       if (!isalpha(keyword[a]))
       return 1;
    }

    //Ciphering
    int keys[b];
    char temporary;
    char c;
    int f;
    int g = 0;
    for (int c = 0; c < b; c++)
    {
       temporary = tolower(keyword[c]);
       keys[c] = (temporary-97)%26;
    }

    int e = strlen(plaintext);
    for (int d = 0; d < e; d++)
    {
       f = g % b;
       if (isalpha(plaintext[d]))
       {
          c = plaintext[d]+keys[f];
          if (c > 122)
          {
             c-=123;
             if (isupper(plaintext[d]))
             {
                c+=65;
             }
             else if (islower(plaintext[d]))
             {
                c+=97;
             }
          }
          printf("%c", c);
          g++;
       }
       else
       {
          c = plaintext[d];
          printf("%c", c);
       }
    }
}
0

Actually, the loops look ok. It's the translation and test logic. I see two problems with your code. One relates to how it wraps around from z to a and how chars are stored. The other is how upper case letters are encoded.

First, your code will add the key to the int value of the letter. If the key is large enough, the int value of letter + key can exceed 127. Here's the problem though. A char is stored in 8 bits, but is also treated as twos complement. When the leftmost bit is a 1, it is treated as a negative number, so anything greater than 127 becomes a negative number. In your code, 'g' + 'z' becomes 103 + 25 = 128 or binary 10000000, which in 2's complement is actually -128. Negative values are undefined. You need to change the logic so that no var defined as a char ever goes above 127.

Now, the second problem has to do with your test logic. The code block that starts with "if (c > 122)" needs to be rethought. While it will work for lower case, it fails for upper case letters that are shifted beyond 'Z'. It isn't correctly wrapping around when, for upper case letters, the int value is translated to anything between 91 and 123 inclusive. ('Z' = 90)

This is definitely a case where some more in-depth debugging and testing would have helped you. For instance, you could have inserted more printf lines that print out both the character and the int values, like this:

         printf("c+=97, c=%i,%c\n",c,c);

It would have clued you in that there was an issue fairly quick. Also, the gdb debugger can be your best friend in debugging too. (Don't remember if gdb has been introduced by this lesson.)

That should get you started. If you think that this has answered your question, please mark it as answered - housekeeping on the forum. If not, after you've worked on it, come back with specific questions and we can go on from there.

| improve this answer | |

You must log in to answer this question.

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