0

I've implemented vigenere.c a long while ago. It got 100 on Gradebook but when I check cs50.me today, it was changed to 90. So, I checked with check50 and it says

:) vigenere.c exists
:) vigenere.c compiles
:) encrypts "a" as "a" using "a" as keyword
:) encrypts "barfoo" as "caqgon" using "baz" as keyword
:) encrypts "BaRFoo" as "CaQGon" using "BaZ" as keyword
:) encrypts "BARFOO" as "CAQGON" using "BAZ" as keyword
:) encrypts "world!$?" as "xoqmd!$?" using "baz" as keyword
:) encrypts "world, say hello!" as "xoqmd, rby gflkp!" using "baz" as keyword
:) handles lack of argv[1]
:) handles argc > 2
:( rejects "Hax0r2" as keyword

The specification said the key must be alphabetic. So, rejecting "Hax0r2" as a keyword is completely normal in my mind because it contains 0. Does check50 go wrong or am I misunderstanding? Please, take a look at my code.

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

int main(int argc, string argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        printf("Usage: ./vigenere key\n");
        return 1;
    }

    // assign argv[1] string to key as string
    string key = argv[1];

    // declare l as length of string, key
    int l = strlen(key); 

    // make sure all characters of key is alphabetic
    for (int n = 0; n < l; n++)
    {
        if (isalpha(key[n]) == false)
        {
            printf("Key must be alphabetic.\n");
            return 2;
        }
    }

    // declare c character for ciphered character
    char c;

    printf("plaintext: ");
    string p = get_string();

    printf("ciphertext: ");

    // iterate through each letter of plaintext til the end, and print it
    for (int i = 0, j = 0; p[i] != '\0'; i++)
    {
        // mod the j with the length of key, not to go far beyond the length of key
        int k = j % l;

        // if ith character of p is alphabetic
        if (isalpha(p[i]))
        {
            // if both ith character of p and kth character of key is uppercased
            if (isupper(p[i]) && isupper(key[k]))   
            {
                int alphaindexK = key[k] - 65; // turn the 'uppercased' kth character of key into alphabetic index
                int alphaindexP = p[i] - 65; // turn the 'uppercased' ith character of p into alphabetic index
                c = ((alphaindexP + alphaindexK) % 26) + 65; // mod alphabetic indexes and then turn it again into 'uppercased' character and assign it to c
                printf("%c", c);
            }
            // if ith character of p is uppercased and kth character of key is lowercased
            if (isupper(p[i]) && islower(key[k]))   
            {
                int alphaindexK = key[k] - 97; // turn the 'lowercased' kth character of key into alphabetic index
                int alphaindexP = p[i] - 65; 
                c = ((alphaindexP + alphaindexK) % 26) + 65; 
                printf("%c", c);
            }
            // if both ith character of p and kth character of key is lowercased
            if (islower(p[i]) && islower(key[k]))   
            {
                int alphaindexK = key[k] - 97; // turn the 'lowercased' kth character of key into alphabetic index
                int alphaindexP = p[i] - 97; // turn the 'lowercased' ith character of p into alphabetic index
                c = ((alphaindexP + alphaindexK) % 26) + 97; // mod alphabetic index and then turn it again into 'lowercased' character and assign it to c
                printf("%c", c);
            }
            // if ith character of p is lowercased and kth character of key is uppercased
            if (islower(p[i]) && isupper(key[k]))   
            {
                int alphaindexK = key[k] - 65; // turn the 'uppercased' kth character of key into alphabetic index
                int alphaindexP = p[i] - 97; 
                c = ((alphaindexP + alphaindexK) % 26) + 97; 
                printf("%c", c);
            }

            // increment j only if p is alphabetic
            j++;
        }
        // if ith character of p is not alphabetic
        else
        {
            printf("%c", p[i]);
        }
    }
    printf("\n");
}
0

If your program is executed without any command-line arguments, with more than one command-line argument, or with one command-line argument that contains any non-alphabetical character, your program should print an error (of your choice) and exit immediately, with main returning 1 (thereby signifying an error).

edit: if check50 fails, i assume i was lazy reading the spec, and its basically always the case!

3
  • True. The case is, let's say I write ./vigenere Hax0r2 and the program should reject by returning 1 as Hax0r2 contains non-alphabetical character 0 and 2, right? And, my program completely follows that rule. I write ./vigenere Hax0r2 and it prints an error and returns 2. It seems that my program is right. But, check50 is saying :( rejects "Hax0r2" as keyword whenever I run it and it gives me 90 in Gradebook. – Htet Oo Wai Yan Jun 26 '17 at 13:49
  • Oh, wait! I found the error. I put return 2 instead of return 1 in checking keyword is alphabetic. I think returning whether 1 or 2 is not important but check50 seems to only accept the "return 1" type. I fixed it and everything is back to normal. Thanks. – Htet Oo Wai Yan Jun 26 '17 at 13:53
  • Glad you found your own correct answer. Can you write it as an answer instead of a comment and accept the answer? Otherwise, it'll sit in the unanswered question pool forever. thanks. – Cliff B Jun 26 '17 at 17:09
0

Answer: Oh, wait! I found the error. I put return 2 instead of return 1 in checking keyword is alphabetic. I think returning whether 1 or 2 is not important but check50 seems to only accept the "return 1" type. I fixed it and everything is back to normal. Thanks.

You must log in to answer this question.

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