CS50- Readability prints only "Before Grade 1" - cs50

#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.

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;
}

Why am I only getting 40% on Caesar?

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.

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");
}
}
}

Write a snippet of C/C++ code that creates this list of base-12 numbers that count from 0000 to BBBB

Im not sure what to do i want it to print 0000 to ending in BBBB i was trying to use the printf statement anyways, if anyone can help me figure this out that would be great. Thanks
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main()
{
char digits[] = "0123456789AB";
for (int column1=0; column1<=12; column1++) {
for (int column2=0; column2<=12; column2++) {
for (int column3=0; column3<=12; column3++) {
for (int column4=0; column4<=12; column4++) {
std::cout<< digits[column2]<<endl;
}
}}}
return(0);
}
The 4 for loops are not the prettiest thing ever, but they should work and I'm not sure it's worth the complications to do it differently. So keep what you have, just print all digits:
std::cout<< digits[column1]<< digits[column2] << digits[column3] << digits[column4]<<endl;
It's better to parametrize the base and the column count to avoid many nested for's.
#include <iostream>
const int columnCount = 4, base = 12;
char digitToChar(int digit) {
if(digit >= 0 && digit <= 9) {
return '0' + digit;
} else {
return 'A' + digit - 10;
}
}
bool increment(int* number) {
int currentColumn = columnCount - 1;
++number[currentColumn];
while(number[currentColumn] == base) {
number[currentColumn] = 0;
--currentColumn;
if(currentColumn < 0) {
return false;
}
++number[currentColumn];
}
return true;
}
void outputNumber(int* number) {
for(int i = 0; i < columnCount; ++i) {
std::cout << digitToChar(number[i]);
}
std::cout << std::endl;
}
int main() {
int number[columnCount] = {0, 0, 0, 0};
bool overflow = false;
do {
outputNumber(number);
overflow = !increment(number);
} while(!overflow);
return 0;
}

Resources