0

I had a rather hard time with the caesar exercise. It consists, for those of you who don't know, in inputing a number and a string, and changing the value of the string's letters by the number, eg. 1, abc = bcd. A few crashes here, optimization there, and I finally came to a version which seemed promising:

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

void validate_parameter(string parameter);

int main(int argc, string argv[])
{
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        exit(1);
    }

    string parameter = argv[1];
    //validate parameter is numeric only
    validate_parameter(parameter);

    int key = atoi(parameter) % 26; 

    string plain = get_string("plaintext: ");
    int m = strlen(plain);
    char cipher[m];

    //Main process, cipher string
    for (int i = 0; i < m; i++)
    {
        int value = plain[i];
        bool upper = false;
        // checks for values
        if (value >= 'A' && value <= 'Z')
        {
            upper = true;
        }
        value = tolower(plain[i]);
        if (value >= 97 && value <= 122)
        {
            value = (plain[i] + key);
            //check value is inbound
            if (value > 122) 
            {
                value -= 26;
            }
        }
        // Makes uppercase uppercase again
        if (upper == true)
        {
            value = toupper(value);
        }
        cipher[i] = value;
    }

    printf("ciphertext: %s\n", cipher);
}
// Checks if value is number
void validate_parameter(string parameter)
{
    int len = strlen(parameter);
    for (int k = 0; k < len; k++)
    {
        if (parameter[k] < '0' || parameter[k] > '9') 
        {
            printf("Usage: ./caesar key\n");
            exit(1);
        }
    }
}

Excited to see my results, I compile and run the program, it asks me for a string and...nothing.
Confused, I try to see what might be causing the problem. After trying for some time, fruitlessly might I add, I consult with an acquainted developer to see what might the problem be. Some time passes and he comes back to me with the results:
Nothing.
Interestingly, however, he told me that, in in another environment with the same resources, the program compiled and ran as expected. I believe, if it is any use, that the environment was called CLion. After a little more testing, however, we found if you remove the validate_parameter function, the code ran, albeit not properly in all instances. A little more digging found the for in the function was what was breaking the code.
He told me to submit the program, to see if the machine could run the code. This is where I want to ask for help: the cs50.me checker managed to run the code, but didn't provide any specific output for me to work with. It says this:

  • :) caesar.c exists.
  • :) caesar.c compiles.
  • :( encrypts "a" as "b" using 1 as key
  • :) encrypts "barfoo" as "yxocll" using 23 as key
  • :) encrypts "BARFOO" as "EDUIRR" using 3 as key
  • :) encrypts "BaRFoo" as "FeVJss" using 4 as key
  • :) encrypts "barfoo" as "onesbb" using 65 as key
  • :( encrypts "world, say hello!" as "iadxp, emk tqxxa!" using 12 as key
  • :) handles lack of argv[1]
    Now, my questions, and the reason I posted the whole program, is:
    Have any of you encountered a similar problem under similar conditions?
    Is it safe to assume its a sandbox problem, and not a code problem?
    My vigenere code is having a similar problem. Could it be the same thing?

1 Answer 1

1

The problem is you are treating a char array as a string here printf("ciphertext: %s\n", cipher);. Which is okay as long as the char array is properly terminated with a null-byte (the thing that makes a string a string!). That explains inconsistent results: the result would depend on where the computer found the first null-byte after the "end" of cipher. It would be impossible to predict, therefore, what the program would output.

You have choices among which are: allocate chipher to the correct size and terminate it properly OR print each char as it is discovered without using cipher.

A note: because of the improperly terminated string, it is possible the output you get looks correct, but there could be "unprintable" characters in the string, so it would not pass check50.

You must log in to answer this question.

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