Getting unexpected results in CS50 readability problem - c

In solving this readability problem, I have been getting some weird unexpected results(expected Grade 16+, getting Grade 10 etc etc), I am not being able to figure out where the bug is or how can I solve it, please help me figure out the bug. The codes are as follows:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
float index;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0f;
S = sc / wc * 100.0f;
index = (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", (int) round(index));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for(int i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for(int i = 0, n = strlen(x); i < n; i++)
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}
The number of letters, words and sentences from these functions are correct so far so I think the problem lies in the main section, probably something to do with the variable type of "L" and "S" or the index formulae, please help me figure out where the problem is. Thank you
here are some of the tests: sentences(expected results)
1.One fish. Two fish. Red fish. Blue fish. (Before Grade 1)
2.Harry Potter was a highly unusual boy in many ways. For one thing, he hated the summer holidays more than any other time of year. For another, he really wanted to do his homework, but was forced to do it in secret, in the dead of the night. And he also happened to be a wizard. (Grade 5)
3.A large class of computational problems involve the determination of properties of graphs, digraphs, integers, arrays of integers, finite families of finite sets, boolean formulas and elements of other countable domains. (Grade 16+)

L = lc / wc * 100.0f;
wrong
L = 100.0f * lc / wc;
right.
When both operands of / are integers, the result is integer as well, so 5/3 == 1.

the OPs code contains several problems, as discussed in the comments to the question.
The following proposed code:
corrects those problems exposed in the comments
cleanly compiles
strongly suggest all those 'global' variables be moved to inside the appropriate functions and when needed else where be passed as parameters.
and now, the proposed code:
//includes
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
//global variables
int lc; //letter count
int wc; //word count
int sc; //sentence count
bool awc; //already word counted
double L; //average number of letters per 100 words
double S; //average number of sentences per 100 words
double i;
//function declaration
int count_letters(string x);
int count_words(string x);
int count_sentences(string x);
//main
int main(void)
{
string text = get_string("text : ");
count_letters(text);
printf("%i letters\n", lc);
count_words(text);
printf("%i words\n", wc);
count_sentences(text);
printf("%i sentences\n", sc);
L = lc / wc * 100.0;
S = sc / wc * 100.0;
i = (0.0588 * L) - (0.296 * S) - 15.8;
if(i < 1.0)
{
printf("Before Grade 1\n");
}
else if(i >= 16.0)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", (int) round(i));
}
}
//functions
int count_letters(string x)
{
lc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
lc += 1;
}
}
return lc;
}
int count_words(string x)
{
wc = 0;
awc = false;
for( size_t i = 0, n = strlen(x); i < n; i++)
{
if((x[i] >= 'a' && x[i] <= 'z') || (x[i] >= 'A' && x[i] <= 'Z'))
{
if(awc == false)
{
wc += 1;
awc = true;
}
}
if(x[i] == ' ')
{
awc = false;
}
}
return wc;
}
int count_sentences(string x)
{
sc = 0;
for( size_t i = 0, n = strlen(x); i < n; i++ )
{
if(x[i] == '.' || x[i] == '!' || x[i] == '?')
{
sc += 1;
}
}
return sc;
}

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

CS50 readability 2022

I am taking CS50x and in PSet 2: Readability throws me the following error when compiling:
Image of the Error message below, easier to read
readability/ $ make readability
readability.c:52:24: error: multi-character character constant [-Werror,-Wmultichar]
if ((txt[i] >= '97' && txt[i] <= '122') || (txt[i] >= '65' && txt[i] <= '90'))
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
2 errors generated.
make: *** [: readability] Error 1
I think it has to be an issue that 97 and all other ASCII codes I am using are not recognized as integers, do I need to specifically declare them? If so, how?
Here is my code:
#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int count_letters(string);
int count_words(string);
int count_sentences(string);
float l;
float w;
float s;
int main(void)
{
// Ask user for string, store in txt.
string txt = get_string("Enter your text: ");
int i = strlen(txt);
// Convert letters and sentences to avg / 100 w.
float L = 100 * (l / w);
float S = 100 * (s / w);
// Calc coleman-liau index
int clindex = round(0.0588 * L - 0.296 * S -15.8);
// Printf "Grade X" if X > 16, printf "Grade 16+".
if (clindex < 1)
{
printf("Grade < 1\n");
}
else if (clindex > 16)
{
printf("Grade 16+\n");
}
else
{
printf("Grade %i\n", clindex);
}
}
int count_letters(string txt)
{
// Count letters
l = 0;
for (int i = 0, n = strlen(txt); i < n; i++)
{
// If the txt is between a-z (97 - 122) or A-Z (65 - 90), increase letter count.
if ((txt[i] >= '97' && txt[i] <= '122') || (txt[i] >= '65' && txt[i] <= '90'))
{
l++;
}
}
return l;
}
int count_words(string txt)
{
// Count words
w = 1;
for (int i = 0, n = strlen(txt); i < n; i++)
{
// If there is a space (ascii 32), then increase word count.
if (txt[i] == 32)
{
w++;
}
}
return w;
}
int count_sentences(string txt)
{
// Count sentences
s = 0;
for (int i = 0, n strlen(txt); i < n; i++)
{
// If txt is . (period 46), ! (exclamation 33), or ? (question 63), inscrease sentence count.
if (txt[i] == 46 || txt[i] == 33 || txt[i] == 63)
{
s++;
}
}
return s;
}
Thank you all for your help.
This code is the problem
if ((txt[i] >= '97' && txt[i] <= '122') || (txt[i] >= '65' && txt[i] <= '90'))
Try this
if (isalpha(txt[i]))
'' quotes are for single character literals.
'a' or 'd' for example.
'123' is more than one character literal.
You probably want to use plain integers instead:
(txt[i] >= 97 && txt[i] <= 122)

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

Why atof function does not work properly?

I am coding in C in a university course and we got a project to take equations from the user and give solutions for matrices etc...
My problem is that I am trying to use atof() function and for a reason I can't find in the same loop once it works and the other times it doesn't.
I have tried already other functions to replace atof like strtod but it doesn't work as well.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdbool>
void main()
{
int num, check = 0,i,j,k=0,len1=0;
char equ[80],tempx[20],tempy[20], tempz[20], tempd[20];
double *x, *y, *z, *d;
printf_s("Number of equations (1-3): ");
scanf_s("%d", &num);
getchar();
while (check == 0) //a check to see if we got a number between 1-3.
{
if (num > 0 && num < 4)
check = 1;
else
{
printf_s("Please enter a number between 1-3.\n");
printf_s("Number of equations (1-3): ");
scanf_s("%d", &num);
}
}
x = malloc(sizeof(double)*num);
if (!x) exit(1);
y = malloc(sizeof(double)*num);
if (!y) exit(1);
z = malloc(sizeof(double)*num);
if (!z) exit(1);
d = malloc(sizeof(double)*num);
if (!d) exit(1);
for (i = 0; i < num; i++) //getting the equations and putting them into the matrix
{
printf_s("Enter equation %d: ", i + 1);
gets_s(equ, sizeof(equ));
len1 = strlen(equ);
for (j = 0; j <len1 ; j++)
{
if (equ[j] == 'x')
{
k = 0;
while ((equ[j-k] != '+' || equ[j-k] != '-') && j-k>=0)
{
tempx[j-k] = equ[j-k];
k++;
}
x[i] = atof(tempx);
}
else if (equ[j] == 'y')
{
k = 0;
while ((equ[j-k] != '+' || equ[j-k] != '-') && j - k >= 0)
{
tempy[j-k] = equ[j-k];
k++;
}
y[i] = atof(tempy);
}
else if (equ[j] == 'z')
{
k = 0;
while ((equ[j - k] != '+' || equ[j - k] != '-') && j - k >= 0)
{
tempz[j-k] = equ[j - k];
k++;
}
z[i] = atof(tempz);
}
else if (equ[j] == '=')
{
k = 0;
while (equ[j+k])
{
tempd[k] = equ[j + k];
k++;
}
d[i] = atof(tempd);
}
}
}
free(x);
free(y);
free(z);
free(d);
}
I expected to get the same result in d[i] as I did in x[i] but every time I try to print d[i] I get 0.0000. When I tried the function _strrev on tempd inside atof I got the reverse result inside d[i].
So the problem was that in the last loop i inserted a string that start with "=" and not a number. Apparently atof() doesn't work when the first char is not a number.

Resources