0

Here's my long code for vigenere.c pset2 homework for cs50.

I asked help from another person and eventual get my codes working. HOWEVER there's one line that i just don't understand!

I use *** to label them out. The line ****m = m % LOK;****

I understand that we need to divide the whole plain text based on the length of the key, but why don't we directly use m instead? Since m will be 0,1,2,3,... and m % LOK will also be 0,1,2,3....

PLEASE HELP!!!!

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

int main (int argc, string argv[])
{
    if ( argc != 2 )
    {
       printf("WRONG\n");
       return 1;
    }
    string k = argv[1];
    int LOK = strlen(k);
    // LOL is the length Of Key from input.

    for (int m = 0; m < LOK; m++)
    {
        if (!isalpha(k[m]))
        {
            printf("Please input letters only!\n");
         return 1;
        }
    }
string text = GetString();


// good to go and no need to fix.
//


    for (int i = 0, m = 0; i < strlen(text); i++)
    {
        if (isalpha(text[i]))
        {
          int key;
          ************m = m % LOK;***************
          if (isupper(k[m]))
           {

            key = k[m] - 65;
           }
          else if (islower(k[m]))
           {
            key = k[m] - 97;
           }
// deal with the cituation that the key has both upper and lower letters.        
                if (islower(text[i]))
                   {
                     // convert small letter
                     printf("%c",(((text[i] - 97) + key) % 26) + 97);

                     m++;  
                   }
                else if (isupper(text[i]))
                   {
                     // convert upper letter
                     printf("%c", (((text[i] - 65) + key) % 26) + 65);

                     m++;  
                   }
        }

                else
                {
                    printf("%c", text[i]);
                   }

    }
   printf("\n");
   return 0;
}
0

I understand that we need to divide the whole plain text based on the length of the key, but why don't we directly use m instead? Since m will be 0,1,2,3,... and m % LOK will also be 0,1,2,3....

Close, but not quite.

@BrendanRafferty has already explained this, but I'm going to make it even clearer.

I think the source of your confusion is that you are reassigning the value of m to m % LOK rather than using a separate int for this. It works fine, but it is more difficult to wrap your head around.

To see more clearly what is going on, declare an extra variable int temp:

for (int i = 0, m = 0; i < strlen(text); i++)
{
    if (isalpha(text[i]))
    {
      int key;
      int temp;
      temp = m % lok;

Let's say the length of your key is three characters, so LOK = 3.

The reason you need to use the modulus operator is so that m > 3 will wrap back around to zero, like so:

   m:   0, 1, 2, 3, 4, 5
temp:   0, 1, 2, 0, 1, 2

If you don't use the modulus operator, m++ will cause the value of the variable to auto-increment beyond the bounds of your keyword array, returning garbage values or causing a segmentation fault. This is what @BrendanRafferty is talking about when he says:

With BAZ as your key, what is k [m] when m is anything greater than 2? The answer is, you don't know.

Hopefully, this explanation makes it clearer for you to see what the % is doing.

Your version works fine, but it never increments m any higher than 2 because it wraps around first. Arguably, this is more efficient than declaring an extra variable -- but it does make it a bit harder to see what's going on.

Hope this helps!

0

With BAZ as your key, what is k [m] when m is anything greater than 2? The answer is, you don't know.

However, if m=3, k [m%LOK]=k [0]="B".

You must log in to answer this question.

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