Why am I only getting 40% on Caesar? - cs50

I'm enrolled to CS50 online and I worked my way through Caesar as well as Vignere in PSet2. I got a score of 99% for Vignere but only 40% on Caesar, which is really strange as I worked off of Caesar for Vigenere.. If anyone could scan through and let me know where my code for Caesar lacks, I would really appreciate it!
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
//user to input number key unprompted
int main(int argc, string argv[])
{
//iterate to make sure only one argument is inputted
if (argc != 2)
{
printf("Usage: ./caesar key \n");
}
else
{ //iterate to make sure the string only has numeric digits
for (int j = 0; j <= (strlen(argv[1])); j++)
{
if (((argv[1][j] >= 'a') || (argv[1][j] >= 'A')) && ((argv[1][j] <= 'z') || (argv[1][j] <= 'Z')))
{
printf("Usage: ./caesar key \n");
return 1;
}
}
//converting digit string to an integer called key
int key = atoi(argv[1]);
if (key < 0) //making sure the key is positive
{
printf("Usage: ./caesar key \n");
return 1;
}
//after validity has been checked
else
{
//prompt user to input plaintext
string plain = get_string("plaintext: ");
int len_plain = strlen(plain);
//convert plaintext to ciphertext using inputted key
string cipher = plain;
for (int x = 0; x < len_plain; x++)
{
if (plain[x] >= 'a' && plain[x] <= 'z')
{
cipher[x] = ((plain[x] + key)%122);
if (cipher[x]<97)
{
cipher[x] = cipher[x] + 96;
}
}
else if (plain[x] >= 'A' && plain[x] <= 'Z')
{
cipher[x] = ((plain[x] + key)%90);
if (cipher[x] < 65)
{
cipher[x] = cipher[x] + 64;
}
}
else
{
cipher[x] = plain[x];
}
}
printf("%s\n", cipher);
}
}
}

From the spec (emphasis added):
... after validating the key, we prompt the user for a string (using
"plaintext: " for the prompt) and then shift all of its characters by
1, printing out "ciphertext: " followed by the result and a newline.
The program does not print "ciphertext: " in the result.

Related

CS50 Readability pset2 debugging

Trying to get through cs50, stuck on readability. Can't figure out what is wrong with my code! When I plug in any length of text it is reading less than grade 1. I know it's got to be something with the counting of the letters, words, sentences but I just can't figure out where I am going wrong. Was hoping for some advice. Thank you!
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
//functions
int count_letters(string text);
int count_words(string text);
int count_sentences(string text);
int main(void)
{
//Prompt user for text
string text = get_string("Text: ");
//variables
int letters = 0;
int words = 1;
int sentences = 0;
//calculate grade level
float L = 100 * ((float)letters / (float)words);
float S = 100 * ((float)sentences / (float)words);
int index = round(0.0588 * L - 0.296 * S - 15.8);
{
if (index > 16)
{
printf("Grade 16+\n");
}
else if (index < 1)
{
printf("Before Grade 1\n");
}
else
{
printf("Grade %i\n", index);
}
}
}
//Count number of letters
int letters = 0;
int count_letters(string text)
{
for (int i = 0; i < strlen(text); i++)
{
if (isalpha(text[i]))
{
letters++;
}
}
return letters;
}
//Count number of words
int words = 1;
int count_words(string text)
{
for (int i = 0; i < strlen(text); i++)
{
if (isspace(text[i]))
{
words++;
}
}
return words;
}
//Count number of sentences
int sentences = 0;
int count_sentences(string text)
{
for (int i = 0; i < strlen(text); i++)
{
if ((text[i] == '!') || (text[i] == '?') || (text[i] == '.'))
{
sentences++;
}
}
return sentences;
}

Why is my integer variable being added to my other integer variable?

I am writing a program that counts the amount of letters and words in a string given by the user. For some reason, the number of words is being added to the number of letters. If there is 3 words in the sentence and 12 letters, then it says that there is 15 words. My code is below:
#include <cs50.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int storeLetters[] = {};
int storeWords[] = {};
// declare functions
int count_letters(string text);
int count_words(string text);
int main(void)
{
// ask user for text passage
string text = get_string("Text: ");
int numOfLetters = count_letters(text);
printf("%d",numOfLetters);
printf(" letters\n");
int numOfWords = count_words(text);
printf("%d",numOfWords);
printf(" words\n");
}
int count_letters(string text)
{
int amountOfLetters = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (isalpha(text[i]))
{
storeLetters[i] += 1;
amountOfLetters += storeLetters[i];
}
else
{
storeLetters[i] += 0;
amountOfLetters += storeLetters[i];
}
}
return amountOfLetters;
}
int count_words(string text)
{
int amountOfWords = 0;
for (int x = 0, n = strlen(text); x < n; x++)
{
if (text[x] == '?' || text[x] == '!' || text[x] == '.' || text[x] == ' ')
{
storeWords[x] += 1;
amountOfWords += storeWords[x];
}
else
{
storeWords[x] += 0;
amountOfWords += storeWords[x];
}
}
return amountOfWords;
}
storeLetters and storeWords are arrays, which you initialize to zero length. If you access storeLetters[0] (or any other index), you go past the end. It's not gonna work.
You don't need those variables at all. Just increment amountOfLetters directly.
int count_letters(string text)
{
int amountOfLetters = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (isalpha(text[i]))
{
amountOfLetters += 1;
}
}
return amountOfLetters;
}

CS50- Readability prints only "Before Grade 1"

#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
string Text = get_string("What is the text? \n");
int letters = 0;
int words = 1;
int sentences = 0;
for (int i = 0, n = strlen(Text); i < strlen(Text); i++)
{
if (isalpha(Text[i]))
{
letters++;
/*printf("%i", letters);*/
}
{
if (isspace(Text[i]))
{
words++;
printf("%i", words);
}
else if (Text[i] == '.' || Text[i] == '!' || Text[i] == '?')
{
sentences++;
printf("%i", sentences);
}
}
//use Coleman-Liau Index
float calculation = (0.0588 * letters / words * 100) - (0.0296 * sentences / words * 100) - 15.8;
int index = round(calculation);
if (index < 1)
{
printf("Before Grade 1\n");
return 0;
}
else if (index >= 16)
{
printf("Grade 16+\n");
return 0;
}
else
{
printf("Grade %i\n", index);
}
}
}
If I remove the return function, it prints out numerous grades which are all different. If I print out with returns included, no matter the Text. it prints out : Before Grade 1. I don't know what I'm doing wrong.

cs50 caeser, I don't understand check50 fail

Below is my code and it is working for 10/11 checks, but shows the error message for this one:
:( encrypts "world, say hello!" as "iadxp, emk tqxxa!" using 12 as key
Cause
expected "ciphertext: ia...", not "ciphertext: ia..."
Log
running ./caesar 12...
sending input world, say hello!...
checking for output "ciphertext: iadxp, emk tqxxa!\n"...
Expected Output:
ciphertext: iadxp, emk tqxxa!
Actual Output:
ciphertext: iadxp, emk tqxxa!
I have no idea why as they look identical to me, what obvious error am I missing here??
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main(int key, string word[])
{
//Ensure only a key of 2 is accepted
if (key != 2)
{
printf("Usage: ./caesar key\n");
return 1;
}
//Ensure the second input has has no letters.
for (int i = 0, n = strlen(word[1]); i < n;)
if (isalpha(word[1][i]))
{
printf("Usage: ./caesar key\n");
return 1;
}
//Ensure each character of the input is a digit
else if (isdigit(word[1][i]))
{
i++;
}
else
{
printf("Usage: ./caesar key\n");
return 1;
}
string text = get_string("Plain text: ");
{
printf("ciphertext: ");
}
{
//check each character is an alphabetical one
for (int b = 0, n = strlen(text); b < n; b++;)
{
int k = 0;
int cipher = 0;
if(!isalpha(text[b]))
{
printf("%c", text[b]);
}
else if (isalpha(text[b]))
{
//Calculate the cipher code for a lower-case letter
if (islower(text [b]))
{
int t = text [b] - 97;
k = (t + atoi(word[1])) % (26);
cipher = k + 97;
//Calculate the cipher code for an upper-case letter
}
else if (isupper(text[b]))
{
int t = text [b] - 65;
k = (t + atoi(word[1])) % (26);
cipher = k + 65;
}
}
//print cipher text.
{
printf("%c", cipher);
}
}
printf("\n");
}
}
First, to see what check50 sees, try this on the failing input.
./caeser 12 | cat -v
cat -v displays unprintable characters. The unprintable characters are coming from here printf("%c", cipher);. That line executes whether the input (text[b]) is alpha or not. That line needs to move inside the else if (isalpha(text[b])) block.

cs50 vigenere - loops incorrectly

Apologies if the answer to this is incredibly simple. I just can't work it out.
I've been working on the CS50 Vigenere problem and I think I'm almost there. However the program loops in a way that I don't expect and I'm not sure why. Once it has printed the first ciphered character of the plaintext, it loops back to move to the next character in the key but misses out the part where it needs to move to the next character of the plain text. At least I think that is what is happening.
Here is my code. Any help would be greatly appreciated.
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, string argv [])
{
int a;
int ciphertext;
int k;
string plain;
int cipher;
// check user has input a valid number of arguments
if (argc < 2 || argc > 2)
{
printf("please input a valid number of arguments\n");
return 1;
}
// check user has input a valid key and prompt for plaintext
char * key = argv [1];
for (a = 0; a < strlen(key); a++)
if (!isalpha(key[a]))
{
printf("Please input a valid key. Key must be alphabetical");
return 1;
}
{
if (a == strlen(key))
{
plain = get_string("Plaintext: ");
}
{
printf("ciphertext: ");
}
}
//read plaintext and keep track
{
for (int i = 0, n = strlen(plain); i < n; i++)
{
//read key and keep track
if (isalpha(plain[i]))
{
for (int j = 0, p = strlen(key); j < p; j++)
//convert key to numerical
{
if (isupper(key[j]) > 'A')
{
k = (key[j] - 65);
//calculate ciphertext and print (upper case)
{
printf("%c", (plain[i] + (k % p) %26) +65);
}
}
else if (islower(key[j]) > 'a')
{
k = (key[j] - 97);
{
printf("%c", (plain[i] + (k % p) %26) +97);
}
}
else printf("%c", plain[i]);
}
}
}
{
printf("\n");
}
}
}

Resources