-6

I've been trying to work through the less comfortable version of cs50's Caesar problem, and would just like to preface this question by saying I'm a complete beginner.

The program is supposed to ask the user to input a key and plaintext, and then cipher that text using the provided key. For example, for a key of 2, "aba" would be "cdc".

I think I managed to get the program running correctly, apart from two things: the output for the ciphertext or encrypted text should be in the form of "Ciphertext: " instead of just the strings outputted, as my program does. The other, more significant problem, is if the inputted key is larger than 26, where the output includes other unwanted symbols instead of just letters.

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

int main (int argc, string argv [])
{
    if (argc != 2)
    {
        printf ("Error. Instructions not followed.\n");
        return 1;
    }
    int key = atoi(argv [1]);
    printf ("%i\n", key);
    printf("Plaintext:");
    string plaintext = get_string();
    int i = 0;
    for (char c = 'A'; c <= 'Z'; c++)
    {
        i++;
    }
    for (int j = 0; j < strlen(plaintext); j++)
    {
        char ciphertext = ((plaintext[j]+key%26));
        if (isupper (plaintext[j]) || islower (plaintext[j]))
        {
            printf("%c", ciphertext);
        }
        if (isalpha (plaintext [j]) == false)
        {
            printf("%c", (plaintext[j]));
        }
    }

printf("\n");
}

Any help would be much appreciated. Thank you.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
nghanima
  • 1
  • 3
  • 1
    C does not have a string type. what is 'string'? – Martin James Sep 09 '17 at 15:24
  • The first for loop doesn't do anything? – Martin James Sep 09 '17 at 15:25
  • '"Ciphertext: "' ?? Where is the code to print it? – Martin James Sep 09 '17 at 15:28
  • C doesn't have a string type built in, but including the cs50 library allows us to use string. Thanks for the point regarding the first loop. Noted and fixed. – nghanima Sep 09 '17 at 15:30
  • 4
    @MartinJames: `typedef char *string;`. That is some CS50 rubbish obfuscation. And one reason not to use this course. – too honest for this site Sep 09 '17 at 15:30
  • @nghanima: "allows us to use string" - No. That is just bad practice: an alias for a `char *`. C does not allow to define custom types. – too honest for this site Sep 09 '17 at 15:31
  • 2
    When a question is tagged CS50 ([tag:cs50]), `string` is a typedef for `char *`. Get used to it, please — people doing CS50 don't know any different because they haven't been taught any different. When it isn't tagged CS50, then you can either add the tag or make pointed jibes about its use. – Jonathan Leffler Sep 09 '17 at 15:41
  • 1
    You need to print `"Ciphertext: "` before you start doing any other output. That's easy to arrange. It isn't obvious what the loop `for (char c = 'A'; c <= 'Z'; c++) { i++; }` is expected to do; it seems like a long-winded way of writing `i = 26;`. It's also pointless since you don't seem to use `i` after that. – Jonathan Leffler Sep 09 '17 at 15:43
  • @JonathanLeffler: "people doing CS50 don't know any different because they haven't been taught any different" - They have been now… – too honest for this site Sep 09 '17 at 15:43
  • 2
    @Olaf: CS50 is my first introduction to C, so I'm afraid I don't yet know what it allows us and doesn't allow us to do. Hopefully in the future I'll be able to figure out what the best practice is. Thanks. – nghanima Sep 09 '17 at 15:44
  • Your 'encryption' line seems to be `char ciphertext = ((plaintext[j]+key%26));`. You are going to need to revisit that — it does not do the job. You need to convert the letter to an offset 0..25 (position within the alphabet), add the offset (modulo 26), and convert the result (0..25) back to a letter. Your code does not get close to that. Take a look at any of the many other questions tagged `[cs50] [caesar-cipher]` (use that as a search term). – Jonathan Leffler Sep 09 '17 at 15:46
  • I don't know anything about CS50. The only string type I knew of that might be relevant is a C++ type. Does CS50 teach anything about debugging before asking students to write stuff like this because, if not, it is rubbish. – Martin James Sep 09 '17 at 15:51
  • @nghanima My condolences. You should get a good book and work through the lessons. CS50 teaches/enforces some bad habits. – too honest for this site Sep 09 '17 at 16:06
  • 2
    An alternative place to get help is https://cs50.stackexchange.com which is an SE site specifically for CS50 students. –  Sep 09 '17 at 16:15
  • @Olaf: any recommendations for good books? It's often difficult to find good resources, specially as a beginner. Thank you. – nghanima Sep 09 '17 at 16:16
  • Agreeing with @Olaf, you should not come away from this exercise thinking that arithmetic on character codes is a good thing or that ASCII is generally used everywhere. The stdio and stdlib functions that you are using are probably not defaulting to an ASCII locale (if your environment even supports an ASCII locale at all), or your compiler using ASCII as the source charset or as the execution charset, or your editor saving your source as ASCII, or your console…. Tip: think of character codes as on a number line. This is really a modulo math problem if you insist on using arithmetic. – Tom Blodget Sep 09 '17 at 18:54

1 Answers1

0

First of all, you have to follow the specifications of the problem. That is, you have to print out the word 'plaintext:' before taking input and print out 'ciphertext:' before giving any output. As the checking process is automated, this becomes very important. Notice the case of those words in your problem statement. Secondly, I will let you figure out the logic by yourself, which is the important part of the problem set. Try watching the next few lectures and learn how to use the debugger in the CS50 IDE. It will help you a lot to solve problems in your code on your own.

akshayk07
  • 2,092
  • 1
  • 20
  • 32