I'm coding a basic program to check if a string is a palindrome or not.
#include <stdio.h>
#include <string.h> //Has some very useful functions for strings.
#include <ctype.h> //Can sort between alphanumeric, punctuation, etc.
int main(void)
{
char a[100];
char b[100]; //Two strings, each with 100 characters.
int firstchar;
int midchar;
int lastchar;
int length = 0;
int counter = 0;
printf(" Enter a phrase or word for palindrome checking: \n \n ");
while ((a[length] == getchar()) !10 ) //Scanning for input ends if the user presses enter.
{
if ((a[length -1]), isalpha) // If a character isalpha, keep it.
{
b[counter] = a[length-1];
counter++;
}
length--; //Decrement.
}
makelower(b, counter); //Calls the function that changes uppercase to lowercase.
for( firstchar = 0; firstchar < midchar; firstchar++ ) //Compares the first and last characters.
{
if ( a[firstchar] != a[lastchar] )
{
printf(", is not a palindrome. \n \n");
break;
}
lastchar--;
}
if( firstchar == midchar )
{
printf(", is a palindrome. \n \n");
}
return 0;
}
//Declaring additional function "makelower" to change everything remaining to lowercase chars.
int makelower (char c[100], int minicount)
{
int count = 0;
while (count <= minicount)
{
c[count] = tolower(c[count]);
}
return 0;
}
And I'm getting the following compiler error on the line with the first while loop, immediately after the printf statement:
p5.c: In function 'main':
p5.c:30: error: expected ')' before '!' token
I've looked up and down, but I haven't found any out-of-place or nonpartnered parenthesis. The only thing I can think of is that I'm missing a comma or some kind of punctuation, but I've tried placing a comma in a few places to no avail.
Sorry if this is too specific. Thanks in advance.
while ((a[length] == getchar()) !10 )
What it looks like you're trying for is assigning to a[length] the result of getchar() and verifying that that is not equal to 10. Which is spelled like so:
while ((a[length] = getchar()) != 10)
= is assignment, == is the test.
Further, your counters are confused. length is initialized to 0 and is only decremented, which will lead to falling off the front of the array after the first decrement. This doesn't get a chance to happen, because you attempt to access a[length-1], which will also fail. This looks like a off-by-one error, also known as a fencepost error, in accessing the character you just read from getchar().
Also, since nothing is checking that the length of recorded input doesn't exceed the length of your buffer a[100], you could fall off the end there as well.
The counters for your palindrome check function are also off. midchar and lastchar are never initialized, midchar is never set, and lastchar is decremented without ever having a value set. You would probably be better off testing a[firstchar] == a[(counter-1)-firstchar].
Related
Basically the program is supposed to allow me to test the words . I am trying learn how to add multiple functions inside the main function but for some reason , I couldn't run the program . Could I know where is my mistake or how can I work on the program .
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
void read_word(int counts[26]);
bool equal_array(int counts1[26] , int counts2[26]);
int main (void)
{
int counts1[26] = {0} , counts2[26] = {0} ;
read_word(counts1);
read_word(counts2);
if(equal_array(counts1, counts2)){
printf("The words are not anagrams");
}
else{
printf("The words are anagrams");
}
return 0;
}
void read_word(int counts[26])
{
char ch , alphabet ;
printf("Enter word: ");
//initialise the letters array first and assign all of them value of 0
for(alphabet = 'a' ; alphabet <= 'z'; alphabet++){
counts[alphabet] = 0;
}
//first loop to get the word and num
while ((ch = getchar()) != '\n')
{
if (isalpha(ch))
{
counts[tolower(ch)]++;
}
counts[ch]++; //Is this statement needed ? why ?
}
}
bool equal_array(int counts1[26] , int counts2[26])
{
char alphabet;
//third loop to check the whole array
for (alphabet = 'a' ; alphabet <= 'z'; alphabet++)
{
if (counts1[alphabet] != counts2[alphabet])
{
return true ;
}
else
{
return false;
}
}
}
As mentioned above in the comment, the ASCII value for 'a' is 97 and 122 for 'z'. When you attempt to iterate:
for(alphabet = 'a' ; alphabet <= 'z'; alphabet++){
counts[alphabet] = 0;
}
You access elements well beyond the end of your array -- invoking Undefined Behavior. See ASCII Table & Description. The irony (as also mentioned in the comment) is the loop is entirely unnecessary because your declaration and initialization of your arrays already set each element in the arrays to zero:
int counts1[26] = {0} , counts2[26] = {0};
While not an error, passing the arrays as, e.g. void read_word(int counts[26]);, shows a misconception of how arrays are treated on access. On access, an array is converted to a pointer to its first elements. This is known as Array / Pointer Conversion and it is set forth in the standard at C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3). What this means is you simply need to provide a pointer as the parameter to represent your arrays in the function arguments, e.g.
void read_word (int *counts);
bool equal_array (int *counts1, int *counts2);
Don't Hardcode Filenames or Use Magic Numbers in Your Code
When you write code, you don't want to sprinkle Magic Numbers (e.g. 26) or hardcode filenames. Instead, if you need a constant, #define one or use a global enum for the same purpose:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#define ALPHA 26 /* if you need a constant, #define one (or more) */
...
int main (void)
{
int counts1[ALPHA] = {0},
counts2[ALPHA] = {0};
Why? If you need to make changes later to the value, you don't have to go picking through each array declaration or loop limit to make changes. You have one single convenient location up top to make the change and it is automatically applied throughout your code.
If you need to pass a filename to your program, pass it as an argument to main() (that's what int argc, char **argv are for) or take input from the user. Why? You shouldn't have to recompile your program just to read from a different filename.
Match Your Variable Type to Function Return Type
Declaring char ch; and then assigning ch = getchar(); is not right. Why? What is the declaration for getchar()? See man 3 getchar. How is it declared and what does it return?
int getchar(void);
The function returns int not char, so you must declare int ch; instead of char ch;. It also allows you to validly check if (ch == EOF).
Your read_word() Function
When you are reading with getchar(), in addition to checking for '\n', you must also check for EOF. There is no guarantee your line will end with '\n'. The user may very well generate a manual EOF with Ctrl + d (or Ctrl + z on windows). Therefore your loop should be:
void read_word (int *counts)
{
int ch; /* ch must be int to match getchar() and catch EOF */
fputs ("Enter word: ", stdout);
while ((ch = getchar()) != '\n' && ch != EOF) /* loop over each char in line */
{
if (isalpha(ch))
{
counts[tolower(ch) - 'a']++; /* map to zero-based index */
}
// counts[ch]++; //Is this statement needed ? why ?
// no - only alpha chars are counted
}
}
Note: tolower() returns lower-case character (e.g. the ASCII value for the lower-case character). Therefore to map the character back to your Zero-Based array index, you must subtract 'a' from the return.
Give Your Functions Names With Plain Meaning
Your equal_array() function returns true if the arrays counts1 and counts2 are NOT equal and returns false if the ARE equal. That is directly opposite of what equal_arrays means. Instead, you could do:
bool equal_array (int *counts1, int *counts2)
{
for (int i = 0; i < ALPHA; i++)
if (counts1[i] != counts2[i])
return false;
return true;
}
(note: there is never the need for an else if all that happens is a return)
Putting it altogether you would have:
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#define ALPHA 26 /* if you need a constant, #define one (or more) */
void read_word (int *counts);
bool equal_array (int *counts1, int *counts2);
int main (void)
{
int counts1[ALPHA] = {0},
counts2[ALPHA] = {0};
read_word(counts1);
read_word(counts2);
if (equal_array(counts1, counts2))
puts ("The words are anagrams");
else
puts ("The words are not anagrams");
return 0;
}
void read_word (int *counts)
{
int ch; /* ch must be int to match getchar() and catch EOF */
fputs ("Enter word: ", stdout);
while ((ch = getchar()) != '\n' && ch != EOF) /* loop over each char in line */
{
if (isalpha(ch))
{
counts[tolower(ch) - 'a']++; /* map to zero-based index */
}
// counts[ch]++; //Is this statement needed ? why ?
// no - only alpha chars are counted
}
}
bool equal_array (int *counts1, int *counts2)
{
for (int i = 0; i < ALPHA; i++)
if (counts1[i] != counts2[i])
return false;
return true;
}
Example Use/Output
$ ./bin/isanagram
Enter word: anagram
Enter word: nag a ram
The words are anagrams
or
$ ./bin/isanagram
Enter word: anagram
Enter word: nag a ham
The words are not anagrams
Now it is working as it should. Let me know if you have any further questions.
As part of an assignment, I am supposed to write a small program that accepts an indefinite number of strings, and then print them out.
This program compiles (with the following warning
desafio1.c:24:16: warning: format not a string literal and no format arguments [-Wform
at-security]
printf(words[i]);
and it prints the following characters on the screen: �����8 ���#Rl�. I guess it did not end the strings I entered by using getchar properly with the null byte, and it prints out garbage. The logic of the program is to initiate a while loop, which runs untill I press the enter key \n, and if there are an space, this is a word that will be store in the array of characters words. Why am I running into problems, if in the else statement once a space is found, I close the word[i] = \0, in that way and store the result in the array words?
#include <stdio.h>
#include <string.h>
int main()
{
char words[100][100];
int i,c;
char word[1000];
while((c = getchar()) != '\n')
{
if (c != ' '){
word[i++] = c;
c = getchar();
}
else{
word[i] = '\0';
words[i] == word;
}
}
int num = sizeof(words) / sizeof(words[0]);
for (i = 0; i < num; i++){
printf(words[i]);
}
return 0;
}
Here are some fixes to your code. As a pointer (as mentioned in other comments), make sure to enable compiler warnings, which will help you find 90% of the issues you had. (gcc -Wall)
#include <stdio.h>
#include <string.h>
int main() {
char words[100][100];
int i = 0;
int j = 0;
int c;
char word[1000];
while((c = getchar()) != '\n') {
if (c != ' '){
word[i++] = c;
} else {
word[i] = '\0';
strcpy(words[j++], word);
i = 0;
}
}
word[i] = '\0';
strcpy(words[j++], word);
for (i = 0; i < j; i++) {
printf("%s\n", words[i]);
}
return 0;
}
i was uninitialized, so its value was undefined. It should start at 0. It also needs to be reset to 0 after each word so it starts at the beginning.
The second c = getchar() was unnecessary, as this is done in every iteration of the loop. This was causing your code to skip every other letter.
You need two counters, one for the place in the word, and one for the number of words read in. That's what j is.
== is for comparison, not assignment. Either way, strcpy() was needed here since you are filling out an array.
Rather than looping through all 100 elements of the array, just loop through the words that have actually been filled (up to j).
The last word input was ignored by your code, since it ends with a \n, not a . That's what the lines after the while are for.
When using printf(), the arguments should always be a format string ("%s"), followed by the arguments.
Of course, there are other things as well that I didn't fix (such as the disagreement between the 1000-character word and the 100-character words). If I were you, I'd think about what to do if the user entered, for some reason, more than 1000 characters in a word, or more than 100 words. Your logic will need to be modified in these cases to prevent illegal memory accesses (outside the bounds of the arrays).
As a reminder, this program does not accept an indefinite number of words, but only up to 100. You may need to rethink your solution as a result.
#include "stdafx.h"
#include "stdlib.h"
#include <ctype.h>
int num = 0;
int i = 0;
int ch = 0;
int letter_index_in_alphabet(int ch) {
if (isalpha(ch) == true) {
char temp_str[2] = { ch };
num = strtol(temp_str, NULL, 36) - 9;
printf("%d is a letter, with %d as its location in the alphabet!", ch, num);
}
else {
return -1;
}
}
int main()
{
char input_str[10];
printf("Please enter a series of up to 10 letters and numbers: \n");
fgets(input_str, 10, stdin);
for (i == 0; i <= 10; i++) {
ch = input_str[i];
letter_index_in_alphabet(ch);
}
return 0;
}
Hello everyone, this is my first post on SOF! The goal of this program is to read characters from the standard input to EOF. For each character, report if it is a letter. If it is a letter, print out its respective index in the alphabet ('a' or 'A' = 1, 'b' or 'B' = 2..etc). I have been searching some other posts on stackoverflow and this has helped me get this far(using fgets and strtol functions). I have no visible syntax errors when I run this code, but after I enter a string of characters (ex: 567gh3fr) the program crashes.
Basically, I am trying to use 'fgets' to bring each character entered into a string with the appropriate index. Once I have that string, I check each index for a letter and if it is, I print the number assigned to that letter of the alphabet.
Any help or insight into why this isn't working as intended is greatly appreciated, Thanks!
You have a few problems.
First, char input_str[10] is only big enough for the user to enter 9 characters, not 10, because you need to allow one character for the null byte that ends a string.
Second, your loop goes too far. For a string with 10 characters, indexes go up to 9, not 10. It also should stop when it gets to the null byte, since the user might not have entered all 9 characters.
To get the position in the alphabet, you can simply subtract the value of A or a from the value of the character. Use tolower() or toupper() to convert the character to the case that you're going to use. Your method works, but it's overly complicated and confusing.
letter_index_in_alphabet() is declared to return int. But when the character is a letter, it doesn't execute a return statement. I'm not sure why it's supposed to return something, since you never use the return value, but I've changed it to return the position (maybe the caller should be the one that prints the message, so the function just does the calculation).
In the for loop, it should be i = 0 to perform an assignment, not i == 0 which is comparison.
You also shouldn't use global variables so much. And system header files should have <> around them, not "".
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
int letter_index_in_alphabet(int ch) {
if (isalpha(ch)) {
int num = tolower(ch) - 'a' + 1;
printf("%d is a letter, with %d as its location in the alphabet!\n", ch, num);
return num;
} else {
return -1;
}
}
int main()
{
char input_str[10];
printf("Please enter a series of up to 9 letters and numbers: \n");
fgets(input_str, sizeof(input_str), stdin);
for (int i = 0; input_str[i]; i++) {
letter_index_in_alphabet(input_str[i]);
}
return 0;
}
I wrote the following code to accept characters from user and enter into an array till he inputs a free space (' ') or a line \n. But code is not functioning. As in, when space bar or return key is pressed in the input, my computer is still accepting values without exiting the loop.
char X[99];
printf ("Type the string without spaces\n");
for (i=0;i<99;i++) {
scanf ("%c",&m);
if(m!=' '&&m!='\n')
X[i]=m;
else i=99;
}
Please explain the error.
First the issue: the default tty mode is canonical, meaning input is made available line by line (see man termios)
Once you fix that, you can use getchar() or read() to get one character at a time. The tty setting, example straight out of the man page of termios .
#include <stdio.h>
#include <termios.h>
int ttySetNoncanonical(int fd, struct termios *prev)
{
struct termios t;
if (tcgetattr(fd, &t) == -1)
return -1;
if (prev != NULL)
*prev = t;
t.c_lflag &= ~ (ICANON);
t.c_cc[VMIN] = 1; // 1-char at a go
t.c_cc[VTIME] = 0; // blocking mode
if (tcsetattr(fd, TCSAFLUSH, &t) == -1)
return -1;
return 0;
}
void main(void) {
printf ("\nType the string without spaces\n");
ttySetNoncanonical(0,NULL); // set to non-canonical mode
char X[1000];
int m, ec=0;
int i;
X[0] = 0;
for (i=0;i<1000;i++) {
//ec = read(0,X+i,1); // read one char at a time
m = getchar();
if(m == EOF || m==' ' || m=='\n') {
X[i] = 0;
break;
}
X[i] = m;
}
printf("You entered %s. Bye.\n\n", X);
}
HTH. You might want to check the boundary condition, in case your user typed in 1000 characters. It works for me on a GNU Linux.
use getch(), scanf() will not work that way.
it would be something like :
for(i=0;i<99;i++)
{
char ch=getch();
if(m!=' ' && m!='\n' && m!='\r')
X[i]=m;
else i=99;
printf("%c",ch);
}
The scanf function reads and ignores any whitespace characters encountered before the next non-whitespace character (whitespace characters include spaces, newline and tab characters). So, instead of
scanf("%c",&m);
use
m = getchar();
The function int getchar ( void ); gets character from stdin, returns the next character from the standard input (stdin). It is equivalent to calling getc with stdin as argument.
Also, the condition should use logical-AND as in:
if(m!=' '&& m!='\n')
Also, outside the loop, write,
X[i] = '\0';
Lets look into the if condition
if(m!=' '||m!='\n')
1. When m is space m=' ' (i.e. ASCII value 32)
m=' '
As per your if condition (Cond1 || Cond2), Cond1 will fail and o/p will be 0 but Cond2 will be TRUE, because it is not ' '.
if(FALSE || TRUE)
will be if(TRUE).
When your input is newline (i.e ASCII value 10).
m='\n'
Here Cond1 will be TRUE because it is not SPACE, due to this it will not check the second condition as per C. and will execute the if(TRUE) statement.
Please try to code it by yourself.... It will help you to clear few C doubts and u will get to know how || and && condition works.
Better to use getchar() instead of scanf in here as you read character by character. Usually we use scanf for get strings as input.
Using the logical operators: && (AND) operator checks for one condition to be false, while or || (OR) operator checks for one condition to be true. So if you use && operator, it checks whether it is a space, and if not, it returns false, without even checking the second condition(EOF). But if you use || operator, as used below, it checks for both cases. Check for more details in operators here
You also have to increment the counter (i) after adding an item to the array (Inside the if) as if you don't, it will continuously add items to the same place of the array, which means you will lost the precious inputs.
So, here's my code:
char X[99];
char m;
printf ("Type the string without spaces\n");
for (i=0;i<99;i++) {
m = getchar();
if(m == ' ' || m=='\n') {
X[i]=m;
i++;
}
else i=99;
}
With the function getch(); it ends if your pressing space or enter!
#include <stdio.h>
int main(void) {
char m, X[99];
int i;
printf("Type the string without spaces\n");
for (i = 0; i < 99; i++) {
m = getch();
if (m == ' ' || m == '\n' || m == '\r')
i=100;
else
X[i] = m;
printf("%c", m);
}
}
try this
#include <stdio.h>
int main(){
int i;
char m, X[99];
printf("Type the string without spaces\n");
for (i=0;i<98;i++){//98 --> sizeof(X) -1
scanf("%c",&m);
if(m!=' ' && m!='\n')
X[i] = m;
else
break;
}
X[i] = '\0';
puts(X);
return 0;
}
Here's a working code:
#include <stdio.h>
int main ()
{
char x[100] = {0};
char m;
int i, j;
printf ("Type:\n");
for (i=0; i<99; i++) {
m = getchar();
getchar();
if ((m != ' ') && (m != '\n')) {
x[i] = m;
} else {
printf ("Breaking.");
break;
}
}
printf ("\n");
for (j=0; j<i; j++)
printf ("%c\n", x[j]);
return 0;
}
Here I have used an extra getchar() to consume the newline used to enter the character m. And so (please note) you will also need to enter a newline after a space (' ') and a newline ('\n') to enter and store these in m and compare them in the next lines.
First error, as everyone has pointed out is the logical operator in the if() statement. It should be
if(m!=' ' && m!='\n')
As you want to check if the entered character is neither a (space) nor a \n, so you have to use the && operator.
Next, the error you are getting is because of something called the trailing character. When you enter a letter and press enter (at the point where your scanf("%c",&m) is asking for input). That letter gets stored in the variable m, but the newline character \n caused by the enter pressed is still in the stdin. That character is read by the scanf("%c",&m) of the next iteration of the for loop, thus the loop exits.
What you need to do is consume that trailing character before the next scanf() is executed. for that you need a getchar() which does this job. So now your code becomes something like this..
#include<stdio.h>
int main()
{
char X[99];
char m;
int i;
printf("Type the string without spaces\n");
for (i=0;i<99;i++)
{
scanf("%c",&m);
if(m!=' ' && m!='\n')
{
X[i]=m;
getchar(); // this statement is consuming the left out trailing character
}
else
i=99;
}
printf("%s",X);
}
Now, the program works exactly as you want.
I want to calculate average word length for a sentence.
For example, given input abc def ghi, the average word length would be 3.0.
The program works but i want to ignore extra spaces between the words. So, given the following sentence:
abc def
(two spaces between the words), the average word length is calculated to be 2.0 instead of 3.0.
How can I take into account extra spaces between words? These are to be ignored, which would give average word length of 3.0 in the example above, instead of the erroneously calculated 2.0.
#include <stdio.h>
#include <conio.h>
int main()
{
char ch,temp;
float avg;
int space = 1,alphbt = 0,k = 0;
printf("Enter a sentence: ");
while((ch = getchar()) != '\n')
{
temp = ch;
if( ch != ' ')
{
alphbt++;
k++; // To ignore spaces before first word!!!
}
else if(ch == ' ' && k != 0)
space++;
}
if (temp == ' ') //To ignore spaces after last word!!!
printf("Average word lenth: %.1f",avg = (float) alphbt/(space-1));
else
printf("Average word lenth: %.1f",avg = (float) alphbt/space);
getch();
}
The counting logic is awry. This code seems to work correctly with both leading and trailing blanks, and multiple blanks between words, etc. Note the use of int ch; so that the code can check for EOF accurately (getchar() returns an int).
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int ch;
int numWords = 0;
int numLetters = 0;
bool prevWasASpace = true; //spaces at beginning are ignored
printf("Enter a sentence: ");
while ((ch = getchar()) != EOF && ch != '\n')
{
if (ch == ' ')
prevWasASpace = true;
else
{
if (prevWasASpace)
numWords++;
prevWasASpace = false;
numLetters++;
}
}
if (numWords > 0)
{
double avg = numLetters / (float)(numWords);
printf("Average word length: %.1f (C = %d, N = %d)\n", avg, numLetters, numWords);
}
else
printf("You didn't enter any words\n");
return 0;
}
Various example runs, using # to indicate where Return was hit.
Enter a sentence: A human in Algiers#
Average word length: 3.8 (C = 15, N = 4)
Enter a sentence: A human in Algiers #
Average word length: 3.8 (C = 15, N = 4)
Enter a sentence: A human in Algiers #
Average word length: 3.8 (C = 15, N = 4)
Enter a sentence: #
You didn't enter any words
Enter a sentence: A human in AlgiersAverage word length: 3.8 (C = 15, N = 4)
Enter a sentence: You didn't enter any words
In the last but one example, I typed Control-D twice (the first to flush the 'A human in Algiers' to the program, the second to give EOF), and once in the last example. Note that this code counts tabs as 'not space'; you'd need #include <ctype.h> and if (isspace(ch)) (or if (isblank(ch))) in place of if (ch == ' ') to handle tabs better.
getchar() returns an int
I am confused why you have used int ch and EOF!
There are several parts to this answer.
The first reason for using int ch is that the getchar() function returns an int. It can return any valid character plus a separate value EOF; therefore, its return value cannot be a char of any sort because it has to return more values than can fit in a char. It actually returns an int.
Why does it matter? Suppose the value from getchar() is assigned to char ch. Now, for most characters, most of the time, it works OK. However, one of two things will happen. If plain char is a signed type, a valid character (often ÿ, y-umlaut, 0xFF, formally Unicode U+00FF, LATIN SMALL LETTER Y WITH DIAERESIS) is misrecognized as EOF. Alternatively, if plain char is an unsigned type, then you will never detect EOF.
Why does detecting EOF matter? Because your input code can get EOF when you aren't expecting it to. If your loop is:
int ch;
while ((ch = getchar()) != '\n')
...
and the input reaches EOF, the program is going to spend a long time doing nothing useful. The getchar() function will repeatedly return EOF, and EOF is not '\n', so the loop will try again. Always check for error conditions in input functions, whether the function is getchar(), scanf(), fread(), read() or any of their myriad relatives.
Obviously counting non-space characters is easy, your problem is counting words. Why count words as spaces as you're doing? Or more importantly, what defines a word?
IMO a word is defined as the transition from space character to non-space character. So, if you can detect that, you can know how many words you have and your problem is solved.
I have an implementation, there are many possible ways to implement it, I don't think you'll have trouble coming up with one. I may post my implementation later as an edit.
*Edit: my implementation
#include <stdio.h>
int main()
{
char ch;
float avg;
int words = 0;
int letters = 0;
int in_word = 0;
printf("Enter a sentence: ");
while((ch = getchar()) != '\n')
{
if(ch != ' ') {
if (!in_word) {
words++;
in_word = 1;
}
letters++;
}
else {
in_word = 0;
}
}
printf("Average word lenth: %.1f",avg = (float) letters/words);
}
Consider the following input: (hyphens represent spaces)
--Hello---World--
You currently ignore the initial spaces and the ending spaces, but you count each of the middle spaces, even though they are next to each other. With a slight change to your program, in particular to 'k' we can deal with this case.
#include <stdio.h>
#include <conio.h>
#include <stdbool.h>
int main()
{
char ch;
float avg;
int numWords = 0;
int numLetters = 0;
bool prevWasASpace = true; //spaces at beginning are ignored
printf("Enter a sentence: ");
while((ch = getchar()) != '\n')
{
if( ch != ' ')
{
prevWasASpace = false;
numLetters++;
}
else if(ch == ' ' && !prevWasASpace)
{
numWords++;
prevWasASpace = true; //EDITED this line until after the if.
}
}
avg = numLetters / (float)(numWords);
printf("Average word lenth: %.1f",avg);
getch();
}
You may need to modify the preceding slightly (haven't tested it).
However, counting words in a sentence based on only spaces between words, might not be everything you want. Consider the following sentences:
John said, "Get the phone...Now!"
The TV announcer just offered a buy-1-get-1-free deal while saying they are open 24/7.
It wouldn't cost them more than $100.99/month (3,25 euro).
I'm calling (555) 555-5555 immediately on his/her phone.
A(n) = A(n-1) + A(n-2) -- in other words the sequence: 0,1,1,2,3,5, . . .
You will need to decide what constitutes a word, and that is not an easy question (btw, y'all, none of the examples included all varieties of English). Counting spaces is a pretty good estimate in English, but it won't get you all of the way.
Take a look at the Wikipedia page on Text Segmentation. The article uses the phrase "non-trivial" four times.