Struggling with CS50 Readability - c

so I'm struggling with why I continue to get undeclared identifiers and can't seem to understand why the code isn't running properly. I'd appreciate any suggestions on how to work through this.
#include <cs50.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int count_letters(string text);
int count_words(string text);
int count_sentences(string text);
int main(void) {
int a;
int b;
int c;
string text = get_string("Text: ");
for (int i = 0; i < strlen(text); i++) {
// Count letters
a = count_letters(text);
// Count words (between spaces), words = space + 1
b = count_words(text);
// Count sentences (# of .?! in text)
c = count_sentences(text);
}
float L = a / (float)b * 100;
float S = c / (float)b * 100;
int CLI = round((0.0588 * L) - (0.296 * S) - 15.8);
if (CLI < 1) {
printf("Before Grade 1\n");
} else if (CLI > 16) {
printf("Grade 16+\n");
} else {
printf("Grade %i\n", CLI);
}
}
int count_letters(string text) {
int letters = 0;
if (text[i] > 'a' && text[i] < 'z' || text[i] > 'A' && text[i] < 'Z') {
letters++;
}
}
int count_words(string text) {
int word = 1;
if (text[i] == ' ') {
words++;
}
}
int count_sentences(string text) {
int sentence = 0;
if (text[i] == '.' || text[i] == '?' || text[i] == '!') {
sentence++;
}
}

I defined the symbol MISSING and implemented the functionality of cs50.h you did not share with us. You can delete all but #include <cs50.h> from that first section.
You iterate over your text in main, so you only need to operate on a single letter c in your count functions (and words is incremented if there were letters but no spaces). This was your main issue.
Moved main() to the end, so you don't need the function declarations for the count functions. Used better variable names and initialized those variables. Not sure what L, S, or CLI are. It would be a good idea to define constants for your magical values (0.0588, 0.296, 15.8).
#define MISSING
#ifndef MISSING
#include <cs50.h>
#else
#include <stdio.h>
#include <stdlib.h>
typedef char * string;
#define MAX_STR 1000
// caller frees returned string
string get_string(const char *prompt) {
char *s = malloc(MAX_STR);
if(!s) return NULL;
printf("%s", prompt);
fgets(s, MAX_STR, stdin);
return s;
}
#endif
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int count_letters(char c) {
return isalpha(c);
}
int count_words(char c) {
return c == ' ';
}
int count_sentences(char c) {
return (c == '.') || (c == '?') || (c == '!');
}
int main(void) {
string text = get_string("Text: ");
int letters = 0;
int words = 0;
int sentences = 0;
for (int i = 0; i < strlen(text); i++) {
letters += count_letters(text[i]);
words += count_words(text[i]);
sentences += count_sentences(text[i]);
}
if(!words && letters) words++;
float L = 100.0 * letters / words;
float S = 100.0 * sentences / words;
int CLI = round((0.0588 * L) - (0.296 * S) - 15.8);
if (CLI < 1) {
printf("Before Grade 1\n");
} else if (CLI <= 16) {
printf("Grade %i\n", CLI);
} else {
printf("Grade 16+\n");
}
return 0;
}

Related

Problem in output of CS50 week 2 Problem set readability

The code is ment to take user input, then compute how many words, letters and sentences are in the input. Then calculate the index.
index = 0.0588 * L - 0.296 * S - 15.8
Where L = average number of letters per hundred words and S is the average number of sentences per 100 words in the text.
if the index is in less than one print "below grade 1" and if it is greater than 16 print "greater than 16". and anything in between should be grade __ (where __ = the index number), For example, if index number = 12. Print grade 12.
In my case the code seems to only be showing the correct output for grades less than 1 and more than 16 and ignoring the other cases.
More details and inputs to the problem here - https://cs50.harvard.edu/x/2022/psets/2/readability/
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int count_letters(string text);
int count_sentances(string text);
int count_words(string text);
int Grade_level(int i, int j, int k);
int main(void)
{
string text = get_string("Text = ");
int num_letters = count_letters(text);
int num_sentances = count_sentances(text);
int num_words = count_words(text);
int gradeLevel = Grade_level(num_letters, num_sentances, num_words);
if (gradeLevel < 1)
{
printf("Before Grade 1\n");
}
else if (gradeLevel > 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade level %d\n", gradeLevel);
}
}
int count_letters(string text)
{
int letters = 0;
for (int i = 0; i < strlen(text); i++)
{
if (isalpha(text[i]))
{
letters++;
}
}
return letters;
}
int count_sentances(string text)
{
int sentances = 0;
for (int i = 0; i < strlen(text); i++)
{
if (text[i] == '.'|| text[i] == '!' || text[i] == '?')
{
sentances++;
}
}
return sentances;
}
int count_words(string text)
{
int words = 1;
for (int i = 0; i < strlen(text); i++)
{
if (text[i] == ' ')
{
words++;
}
}
return words;
}
int Grade_level(int num_letters, int num_words, int num_sentances)
{
float index, L, S;
L = (num_letters/num_words) * 100;
S = (num_sentances/num_words) * 100;
index = (0.0588 * L) - (0.296 * S) - 15.8;
index = round(index);
return (int)index;
}

Why does my code repeat the output of the grade level when ran. This is Harvard's CS50 pset2 called readability

I thought the code was fine until I tested using "Red fish, blue fish, one fish, two fish." and it gave me the correct output (Below Grade 1) but it said it a bunch of times. I know the problem is most likely in my loop but I can't find the issue in it.
int main(void)
{
//Text from User
string text = get_string("Text: ");
int letters = 0;
int words = 1;
int sentences = 0;
for (int i = 0; i < strlen(text); i++)
{
if (isalpha(text[i]))
{
letters++;
}
else if (text[i] == ' ')
{
words++;
}
else if (text[i] == '.' || text[i] == '!' || text[i] == '?')
{
sentences++;
}
float L = (float) letters / (float) words * 100;
float S = (float) sentences / (float) words * 100;
int index = round(0.0588 * L - 0.296 * S - 15.8);
if (index < 1)
{
printf("Before Grade 1\n");
}
else if (index > 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", index);
}
You are missing header files, depend on code you didn't share with us (get_string()) and your source is truncated. You need to do the calculations after the loop:
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char * string;
#define LEN 1000
string get_string(const char *prompt) {
printf("%s", prompt);
string s = malloc(LEN + 1);
if(!fgets(s, LEN, stdin)) {
free(s);
return NULL;
}
size_t n = strlen(s);
if(n) n--; // strip trailing newline
s[n] = '\0';
return s;
}
int main(void) {
string text = get_string("Text: ");
int letters = 0;
int words = 1;
int sentences = 0;
for (size_t i = 0; i < strlen(text); i++) {
if (isalpha(text[i])) {
letters++;
} else if (text[i] == ' ') {
words++;
} else if (text[i] == '.' || text[i] == '!' || text[i] == '?') {
sentences++;
}
}
float L = (float) letters / (float) words * 100;
float S = (float) sentences / (float) words * 100;
int index = round(0.0588 * L - 0.296 * S - 15.8);
if (index < 1) {
printf("Before Grade 1\n");
} else if (index > 16) {
printf("Grade 16+\n");
} else {
printf("Grade %i\n", index);
}
free(text);
return 0;
}

Readability, why won't Coleman-Liau index formula work when I plugin words, letters, and sentences?

whats wrong with my code? this is the part that doest work
float L = (letters / words) * 100; and float S = (sentences / words) * 100;
when I plug in letters, words, and sentences into the formula it gives the wrong answer.
#include <stdio.h>
#include <string.h>
#include <cs50.h>
#include <ctype.h>
#include <math.h>
int main(void)
{
char ch[500];
int i;
int ii;
int iii;
int LettersWspace = 0;
int letters = 0;
int words = 1;
int sentences = 0;
int index;
string text = get_string("Enter Text: ");
for(i = 0; text[i] != '\0'; i++)
{
LettersWspace++;
}
for( i = 0; i < LettersWspace; i++)
{
if (text[i] == 32)
letters++;
}
letters = LettersWspace - letters;
ii = 0;
{
if (text[ii] == ' ')
{
words++;
}
ii++;
}
while (ii <= text[ii]);
iii = 0;
do
{
if (text[iii] == '?' || text[iii] == '!' || text[iii] == '.')
{
sentences++;
}
iii++;
}
while (iii <= text[iii]);
float L = (letters / words) * 100;
float S = (sentences / words) * 100;
return (index = 0.0588 * L - 0.296 * S - 15.8);
printf("%i\n", (int) sentences);
return 0;
}

String won't store more than one word (C)

This is the first step in a program I have written.
The objective: A user needs to write a sentence, and my program needs to store it in an array. This can be as short or long as they like.
My program: Runs with no technical errors
The issue: When I run the program, I am unable to submit anything more than 1 word. 'Hello' submits and the program executes. Anything more than that - new words, spaces, punctuation and numbers, when I hit enter - I just keep jumping to a new line in my terminal and the program doesn't go to the next step.
This is the code I am using to
Prompt the user for text and
Store the answer.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int main(void)
{
string z = get_string("Text: \n");
// int n = strlen(z);
int a = 0;
int d = 1;
int e = 0;
while (z[a] != '\0')
{
while (isalpha(z[a]))
{
a++;
}
while (z[a] ==' ')
{
d++;
}
//Count the sentences
while (z[a] == '.' || z[a] == '!' || z[a] == '?' || z[a] == '/')
{
e++;
}
}
// printf("%i letter(s)\n", a);
// printf("%i word(s)\n", d);
// printf("%i sentence(s)\n", e);
//Coleman-Liau index formula
int m = (0.0588 * (100 * a / d) - 0.206 * (100 * e / d) - 15.8);
if (m <= 1)
{
printf("Before Grade 1\n");
}
if (m >= 16)
{
printf("Grade 16+\n");
}
if (m < 16)
{
printf("Grade %i\n", m);
}
}
Pretty new to coding and any help will be appreciated!
Screenshot of my terminal
The problem is that the while loops that count words and sentences never increment a, which is the index into z. So they keep testing the same character over and over and you're in an infinite loop.
It works for a single word because those tests never succeed in the first place.
You also shouldn't be using the variable that counts letters as the array index.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int main(void)
{
char *z = get_string("Text: \n");
// int n = strlen(z);
int i = 0;
int a = 0;
int d = 1;
int e = 0;
while (z[i] != '\0')
{
int counted = 0;
while (isalpha(z[i]))
{
a++;
i++;
counted = 1;
}
while (z[i] ==' ')
{
d++;
i++;
counted = 1;
}
//Count the sentences
while (z[i] == '.' || z[i] == '!' || z[i] == '?' || z[i] == '/')
{
e++;
i++;
counted = 1;
}
if (!counted) {
i++;
}
}
// printf("%i letter(s)\n", a);
// printf("%i word(s)\n", d);
// printf("%i sentence(s)\n", e);
//Coleman-Liau index formula
int m = (0.0588 * (100 * a / d) - 0.206 * (100 * e / d) - 15.8);
if (m <= 1)
{
printf("Before Grade 1\n");
}
if (m >= 16)
{
printf("Grade 16+\n");
}
if (m < 16)
{
printf("Grade %i\n", m);
}
}
the following proposed code:
cleanly compiles using: gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled2.c" -o "untitled2.o"
performs the desired functionality
uses meaningful variable names
uses a unique variable name for stepping through the text
does not include header files those contents are not used
uses a for() loop for stepping through the text
uses size_t rather than int variables because the contents of those variables will never be <0
and now the proposed code:
#include <cs50.h>
#include <stdio.h>
//#include <string.h>
//#include <math.h>
#include <ctype.h>
int main(void)
{
string z = get_string("Text: \n");
size_t spaces = 0;
size_t sentences = 0;
size_t letters = 0;
for( size_t i = 0; z[i]; i++ )
{
if( z[i] ==' ' )
{
spaces++;
}
if( isalpha( z[i] ) )
{
letters++;
}
//Count the sentences
if( z[i] == '.' || z[i] == '!' || z[i] == '?' || z[i] == '/')
{
sentences++;
}
}
// printf("%i letter(s)\n", a);
// printf("%i word(s)\n", d);
// printf("%i sentence(s)\n", e);
//Coleman-Liau index formula
int m = (int)(0.0588 * (double)(100 * letters / spaces) - 0.206 * (double)(100 * sentences / spaces) - 15.8);
if (m <= 1)
{
printf("Before Grade 1\n");
}
if (m >= 16)
{
printf("Grade 16+\n");
}
if (m < 16)
{
printf("Grade %i\n", m);
}
}
a typical run of the program:
Text:
a quick brown fox jumped over a lazy dog
Grade 7

Strange unwanted three digit code printouts from caesar cipher

The cipher code actually works; it's just that I get some odd three digit codes separated with slashes too.
Any help would be greatly appreciated. Here's my code.
The codes look like this but have random numbers /354/233/645/810/236
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cs50.h"
int i, len;
string sentance, encrypted;
int k, argvLen;
int caesar (int k){
printf("Hi I'm Ceaser! What would you like me to cipher?\n");
sentance = GetString();
len = strlen(sentance);
char encrypted[len];
for (i=0; i<len; i++) {
if (sentance[i] >='a' && sentance[i] <='z') {
encrypted[i] = ((sentance[i] - 'a' + k) % 26) + 'a';
}
else if (sentance[i] >='A' && sentance[i] <='Z') {
encrypted[i] = ((sentance[i] - 'A' + k) % 26) + 'A';
}
else if (sentance[i] >=' ' && sentance[i] <= '#'){
encrypted[i] = sentance[i];
}
}
printf("%s", encrypted);
return 0;
};
int main (int argc, const char * argv[]) {
if (argc==2) {
k = atoi(argv[1]);
argvLen = strlen(argv[1]);
for (i=0; i<argvLen; i++){
if (isdigit(argv[1][i])){
caesar(k);
}
else {
printf("please enter a number for the key!");
return 1;
}
}
return 0;
}
};
You are not terminating the encrypted string properly.
You need:
To make sure you have room for the terminating character, by using char encrypted[len + 1];.
encrypted[len] = '\0'; after the loop.

Resources