caesar.c

Here is the reference solution for Problem Set 2, caesar.c

// Encrypt a message using the Caesar cypher, with a user-provided key.
// This is CS50x pset2 caesar.c
//
// Author: david@newtongwc.org
//
// Usage: caesar <secret>
//
// Reads the (new-line-terminated) clear-text message from stdin, writes the
// crypt-text message to stdout.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <cs50.h>
#define true 1
#define false 0
int ArgsAreValid(int argc, string argv[]) {
    if (argc != 2) {
        printf("Error: You must supply exactly 1 argument to %s\n", argv[0]);
        return false;
    }
    if (atoi(argv[1]) < 0) {
        printf("Error: The ceaser secret must be a non-negative integer\n");
        return false;
    }
    return true;
}
int GetSecret(int argc, string argv[]) {
    return atoi(argv[1]);
}
// Encrypt a single character by shifting it some number ("secret") of places
// up the alphabet, wrapping around from 'z' to 'a'. Works for both upper- and
// lower-case letters, staying within the same case. Leaves non-alphabetic
// characters unchanged.
char EncryptChar(char clear, int secret) {
    char crypt = 0;
    if (isupper(clear)) {
        crypt = (clear - 'A' + secret) % 26 + 'A';
    } else if (islower(clear)) {
        crypt = (clear - 'a' + secret) % 26 + 'a';
    } else {
        crypt = clear;
    }
    return crypt;
}
// Encrypts a full message, one character at a time, using the provided
// encryption secret.
string Encrypt(string clear_text, int secret) {
    string crypt_text = malloc(strlen(clear_text) * sizeof(char));
    int num_chars = strlen(clear_text);
    for (int i = 0; i < num_chars; ++i) {
        crypt_text[i] = EncryptChar(clear_text[i], secret);
    }
    return crypt_text;
}
int main(int argc, string argv[]) {
    if (!ArgsAreValid(argc, argv)) {
        return 1;
    }
    int secret = GetSecret(argc, argv);
    string clear_text = GetString();
    string crypt_text = Encrypt(clear_text, secret);
    printf("%s\n", crypt_text);
    free(clear_text);
    free(crypt_text);
    return 0;
}