-3

I can get it to print the plaintext and and shift by the key value, but i'm a bit confused on how to get the letters to wrap around, and how to implement it into my code.

Any suggestions would be appreciated.

Thank you.

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

//Gets number of user arguments and the key.
int main (int argc,  string argv[]) { 
    if(argc != 2) {
        printf("try again\n");
    }
    //Converts string to int. 
    int key = atoi(argv[1]);

    //Will store the chars + key. 
    int result;

    printf("Please enter what you would like to encrypt: "); 

    //Gets plaintext from user. 
    string plainText = get_string();       

    //Iterates over the user's input, checking for the case of each char. 
    for (int i = 0; i <= strlen(plainText); i++) {
        if (toupper(plainText[i]) || tolower(plainText[i])) { 
                    result = plainText[i]; 
        }
    //Checks if i'th char is a letter and shifts it. 
        if (isalpha(plainText[i])) { 
                    result = plainText[i + key]; 
        } 
    } 
    printf("%c", result);  
}
Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
ncubed
  • 41
  • 1
  • 8
  • Possible duplicate of [Homework(revision): Caesar cipher, wrap around when char's are >'z' (c++)](http://stackoverflow.com/questions/8489474/homeworkrevision-caesar-cipher-wrap-around-when-chars-are-z-c) – Ari0nhh Jan 16 '17 at 03:45
  • 2
    What is this supposed to do: `if (toupper(plainText[i]) || tolower(plainText[i]))`? – ad absurdum Jan 16 '17 at 04:39

1 Answers1

3

One of the neatest tricks to do this is to use the modulo % operator.

Now talking about your code,

for (int i = 0; i <= strlen(plainText); i++) {
if (toupper(plainText[i]) || tolower(plainText[i])) { 
            result = plainText[i]; 
}
//Checks if i'th char is a letter and shifts it. 
if (isalpha(plainText[i])) { 
            result = plainText[i + key]; 
  } 
} 
printf("%c", result);  

This code makes no sense to me. Your first if condition is I guess to distinguish of the not alphabetical characters, so the if condition could be something like if (! isalpha(plainText[i]) ,

Then your second condition is to add the key to the character if it is an alphabet. It should be something like

if (isalpha (plainText[i])) {
    if (islower(plainText[i]) 
        result = ((plainText[i] - 'a') + key) % 26 + 'a';
    else
        result = ((plainText[i] - 'A') + key) % 26 + 'A';

}

Explanation of above logic:: First you check weather the letter is lowercase or uppercase, so that you can make it in range of 0 to 26, Then you add the key with the modulo of key, so that it can circle back to 0, then you again convert that it to ascii by adding the value of 'a' their.

e.g. if plainText[i] = 'x' (ascii value 120) and key = 5, then

plainText[i] =  120
plaintext[i] - 'a' = 23
(plaintext[i] - 'a') + key = 28 // Out of 0-25 alphabet range
((plaintext[i] - 'a') + key) % 26 = 2 // Looped back
(((plaintext[i] - 'a') + key) % 26) + 'a' = 99 (ascii value for 'c')

So as you can see we got c after adding 5 to x

And finally the position of your print should be inside loop, otherwise it's gonna only print the last input, which is not correct.

I hope I did everything to help you, keeping in mind the CS50's Honor Code. And also I would suggest you to ask these questions in their forums, because they are a more knoledgeble community to use <cs50.h>

Also, enjoy CS50, it is one of the best CS courses to get you started ;)

NVS Abhilash
  • 574
  • 7
  • 24
  • Thank you so much for your help. – ncubed Jan 16 '17 at 05:49
  • It would be better to use character constants instead of integer constants: `result = ((plainText[i] - 'A') + key) % 26 + 'A';`. This makes the meaning more clear. – ad absurdum Jan 16 '17 at 05:52
  • @David, thanks for your advice, I have updated the answer. – NVS Abhilash Jan 16 '17 at 08:25
  • Just a comment about portability: the Standard does not specify ASCII encoding for the execution character set, and in fact other encodings do occur (e.g., EBCDIC was used on some IBM systems). This solution will _probably_ work, but where portability is a concern another approach may be needed. – ad absurdum Jan 16 '17 at 08:32
  • There are a few other issues with OP's code. An `exit()` statement needs to accompany the error message at the beginning. `result` needs to be assigned the current character at the start of each loop iteration. The `printf()` statement that prints the encoded character needs to be moved inside of the loop. – ad absurdum Jan 16 '17 at 08:49
  • Thanks David for your input, I think the answer is sufficient to point Nicholas in right direction, it is not a complete solution. I think that's what is expected when you answer a CS50 problem IMHO. – NVS Abhilash Jan 16 '17 at 08:52
  • How do I mark as answered? my apologies, I'm still learning how to navigate this site. – ncubed Jan 16 '17 at 16:42
  • Well, you can surely Google it. Remember, Google is your friend to all the silly questions. Don't worry it will take time, but it will all make sense after some time ;) – NVS Abhilash Jan 16 '17 at 17:15