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
Related
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;
}
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;
}
In week 2 of CS50, having problems creating the readability program. No idea how to fix my code at the moment.
This is what I get when checking the code:
https://submit.cs50.io/check50/882c9f1f8fbbb109d3ef495101233c72a995b880
This is all new to me so would appreciate some help from any seasoned C programmer out there.
Thank you in advance.
Below is the code.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
int main(void)
{
/* Get the text fromn the user */
string text = get_string("Text: ");
/* Initiate 3 integers to count words,letters and sentences*/
int letters = 0, words = 0, sentences = 0;
/* Loop to iterate through the text and count the values initated above */
for (int i = 0; i < strlen(text); i++)
{
if (isalpha(text[i]))
{
letters++;
}
if (isspace(text[i]))
{
words++;
}
if (text[i] == '.' || text[i] == '!' || text[i] == '?')
{
sentences++;
}
}
/* Initiate floats to use with Coleman-Liau index */
float l = letters / words * 100, s = sentences / words * 100, index = 0.0588 * l - 0.296 * s - 15.8;
/* round the float into the closest integer*/
int grade = round(index);
/* print the grade after text analysis*/
if (grade >= 1 && grade <= 16)
{
printf("Grade %i\n", grade);
}
else
{
if (grade < 1)
{
printf("Before Grade 1\n");
}
if (grade > 16)
{
printf("Grade 16+\n");
}
}
}
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;
}
Why does the final section, Grade, not calculate?
I mean, why is it not carrying through to the final section of the program?
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
int main(void)
{
char text[1000];
int number = 0;
int words = 0, i;
int sentences = 0, j;
float l = ((number +1) / (words +1)) * 100;
float s = ((sentences+1) / (words+1)) * 100;
float index = (0.0588 * l) - 0.296 * s - 15.8;
// Text Input = Text //
printf("Text: ");
fgets(text, sizeof(text), stdin);
printf("%s", text);
// Letters = number //
number = strlen(text);
printf("%d letters\n", number);
// Words = words //
for (i = 0; text[i] != '\0'; i++)
{
if (text[i] == ' ' && text[i+1] != ' ')
words++;
}
printf("%d words\n", words);
// Sentences = sentences
for (j = 0; j < strlen(text); j++)
{if (text[j] == '.' || text[j] == '!' || text[j] == '?')
sentences++;
}
printf("%d sentences\n", sentences);
// grade level based on formula //
if (index >= 1 && index <= 16)
{
printf("Grade %f\n", index);
}
else
{
if (index < 1)
{
printf("Before Grade 1\n");
}
if (index > 16)
{
printf("Grade 16+\n");
}
}
}
Any feedback would be of significance.
I suspect it's due to the integer identities assigned to the initial variables of number, words, and sentences, yet I do not have a clue how to improve upon this. It's just the final grade portion that is impeding my progress and understanding.