Count how many times a word is used. C - c

I am trying to count the number of loops and emptylines in a string entered by a user. So here is the way I did it:
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
int main(void) {
int i, lines, loopF = 0, loopW = 0, loopDW = 0, empty = 0;
char *p, str[200];
const char test[10] = "while";
char *f;
printf("Enter a string. Ctrl+Z for exit.\n");
while (fgets(str, 200, stdin) != NULL) {
if (f = strstr(str, test)) { //first way
loopW++;
}
for (i = 0; i < strlen(str); i++) {
// count loops
if (str[i] == 'f' && str[i + 1] == 'o' && str[i + 2] == 'r') {
loopF++;
}
if (str[i] == 'w' && str[i + 1] == 'h' && str[i + 2] == 'i'
&& str[i + 3] == 'l' && str[i + 4] == 'e') { // second way
loopW++;
}
if (str[i] == 'd' && str[i + 1] == 'o') {
loopDW++;
if (loopDW >= 1)
loopW--;
}
}
// count empty lines
p = str;
lines = 0;
while (*p != '\n') {
if (*p != ' ') {
lines = 1;
}
p++;
}
if (!lines) {
empty++;
lines = 0;
}
}
printf("---------------------\n");
printf(" Empty lines: %d \n\n", empty);
printf(" Number of loops:\n");
printf(" For: %d \n", loopF);
printf(" While: %d \n", loopW);
printf(" Do/While: %d \n", loopDW);
printf("---------------------\n");
return 0;
}
I did it for 2 ways only for "while" to test but when a user types "whilethis" or "thiswhile" it counts it(which is not what I want). I want when there is only a while(a loop) to be counted and not with other symbols but i have no idea how to do it. Same is for do/while and for loops. Any help here? :)

The proper solution also needs to handle strings and comments
print("I have no for() loops")
/* commented out for() loop */
char* c = "for()\"loop\\";
If you do not care about this, and really want to use plain C, I would recommend "strtok" function which splits string into the words using delimiters (which would be basically all non-alphanumeric symbols in your case -- space, brackets, comma, etc...). Then once you have words, you can just strcmp() them with "do", "while" or "for"

Related

Program to count the total number of vowels, consonants and words and ask for a user again for check for a letter for a string

Program to count the total number of vowels, consonants, words and ask for a user again to check how many times a word has been used in that sentence checking in a string.
At this point my code does checks vowels and consonants and after this program has to ask for a word to the user to input a word and check how many times ıts been used in that sentence.
#include <stdio.h>
void main() {
char sentence[80];
int i, vowels = 0, consonants = 0, special = 0;
printf("Enter a sentence \n");
gets(sentence);
for (i = 0; sentence[i] != '\0'; i++) {
if ((sentence[i] == 'a' || sentence[i] == 'e' ||
sentence[i] == 'i' || sentence[i] == 'o' ||
sentence[i] == 'u') ||
(sentence[i] == 'A' || sentence[i] == 'E' ||
sentence[i] == 'I' || sentence[i] == 'O' ||
sentence[i] == 'U')) {
vowels = vowels + 1;
} else {
consonants = consonants + 1;
}
if (sentence[i] == '\t' ||sentence[i] == '\0' || sentence[i] == ' ') {
special = special + 1;
}
}
consonants = consonants - special;
printf("No. of vowels in %s = %d\n", sentence, vowels);
printf("No. of consonants in %s = %d\n", sentence, consonants);
}
Here are some problems in your code:
void main() is invalid: you should write int main()
gets(sentence); is risky as input longer than 79 bytes will cause a buffer overflow. This function is a security flaw and has been removed from current versions of the C Standard. You should use fgets() instead and check the return value.
you only test for TAB and SPACE as special characters, so any punctuation will be counted as consonant letters.
you do not count the number of words
you only implement the first part of the assignment.
Here is a modified version using ancillary functions:
#include <stdio.h>
#include <string.h>
int is_letter(char c) {
// Assuming ASCII
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
int is_vowel(char c) {
return c != '\0' && strchr("aeiouAEIOU", c) != NULL;
}
int main() {
char sentence[80];
printf("Enter a sentence \n");
if (fgets(sentence, sizeof sentence, stdin)) {
int i, vowels = 0, consonants = 0, words = 0;
char c, lastc = 0;
for (i = 0; sentence[i] != '\0'; i++) {
c = sentence[i];
if (is_letter(c)) {
if (is_vowel(c)) {
vowels = vowels + 1;
} else {
consonants = consonants + 1;
}
if (!is_letter(last)) {
words = words + 1;
}
}
last = c;
}
printf("No. of vowels = %d\n", vowels);
printf("No. of consonants = %d\n", consonants);
printf("No. of words = %d\n", words);
// implement the rest of the assignment...
}
return 0;
}

Make first letter of every word capital after removing vowels

My code works to delete any vowels and prints the first letter of the word as a capital letter.
How can I get my expected output to work?
If the value is " I am Iron Man" (with a leading space), it works and prints "M Rn Mn".
However, without the space at the beginning of the string, my output is "m Rn Mn" but
the expected output is "M Rn Mn".
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char str[] = "I am Iron Man";
int i, j, len = 0;
len = strlen(str);
// Accepting input.
for (i = 0; i < len; i++) {
// Check vowels.
if (str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u' ||
str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U') {
// delete vowel syntax
for (j = i; j < len; j++) {
// Store after removing vowels
str[j] = str[j + 1];
}
i--;
len--;
}
str[len + 1] = '\0';
}
for(i=0; str[i]!='\0'; i++)
{
//check first character is lowercase alphabet
if(i==0)
{
if((str[i]>='a' && str[i]<='z'))
str[i]=str[i]-32; //subtract 32 to make it capital
continue; //continue to the loop
}
if(str[i]==' ')//check space
{
//if space is found, check next character
++i;
//check letter if lowercase
if(str[i]>='a' && str[i]<='z')
{
str[i]=str[i]-32; //subtract 32 to make it capital
continue; //continue to the loop
}
}
}
printf("%s", str);
return 0;
}
Your problem lies with excessive use of the continue statement in the second for loop. The second continue is just plain pointless, as control reaches the end of the loop, anyway, after the point where you have that.
But the first continue is actually causing the fault: after removal of the vowels, the first character in the modified string will be a space – so, the first if block inside the second loop will be entered, and that will skip the check for a lowercase letter following the space.
Removing those continue statement will fix your code.
Also, note that you can use the islower and toupper functiosn to check for lowercase letters and convert to uppercase:
#include <stdio.h>
#include <string.h>
#include <ctype.h> // For islower and toupper
int main()
{
char str[] = "I am Iron Man";
size_t i, j, len = 0;
len = strlen(str);
// Accepting input.
for (i = 0; i < len; i++)
{
// Check vowels.
if (str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u' ||
str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U') {
// delete vowel syntax
for (j = i; j < len; j++)
{
// Store after removing vowels
str[j] = str[j + 1];
}
i--;
len--;
}
str[len + 1] = '\0';
}
for (i = 0; str[i] != '\0'; i++)
{
//check first character is lowercase alphabet
if (i == 0)
{
if (islower(str[i])) {
str[i] = toupper(str[i]);
}
// A "continue" here is wrong ... it will skip the following check for a lowercase letter
}
if (str[i] == ' ') //check space
{
//if space is found, check next character
++i;
//check letter if lowercase
if (islower(str[i]))
{
str[i] = toupper(str[i]);
// No need for a "continue" here ... we're already at the end of the loop
}
}
}
printf("%s\n", str);
return 0;
}
I have another solution for you, that may be a bit easier to comprehend:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char str[] = "I am Iron Man";
char *in;
char *out;
int up = 1; // very simple state, if "up" then next character should be made upper
for (in = str, out = str; *in; in++) {
if (strchr("aeiouAEIOU", *in) != NULL) {
// do nothing
} else if (*in == ' ') {
*out++ = *in;
up = 1; // we see a space, so next letter should be upper
} else if (up) {
*out++ = toupper(*in);
up = 0; // we see a letter (or other character), ignore case
} else {
*out++ = *in;
}
}
*out = '\0';
printf("%s\n", str);
}
Or, if you don't like/understand the pointer syntax:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char str[] = "I am Iron Man";
int i;
int o;
int up = 1; // very simple state, if "up" then next character should be made upper
for (i = 0, o = 0; str[i]; i++) {
if (strchr("aeiouAEIOU", str[i]) != NULL) {
// do nothing
} else if (str[i] == ' ') {
str[o++] = str[i];
up = 1; // we see a space, so next letter should be upper
} else if (up) {
str[o++] = toupper(str[i]);
up = 0; // we see a letter (or other character), ignore case
} else {
str[o++] = str[i];
}
}
str[o] = '\0';
printf("%s\n", str);
}
In both cases, a very simple state is used. For more complex conditions, you should learn about state machines. In this case, the up state indicates that the next letter should be capitalised.
Note that if you want to remove leading spaces, after "removing" the vowels, you need to modify the logic a bit:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char str[] = "I am Iron Man";
char *in = str; // we initialize in and out here already
char *out = str;
int up = 1; // very simple state, if "up" then next chacter should be made upper
// we skip leading vowels AND spaces, this is a special case
while (*in && (strchr("aeiouAEIOU ", *in) != NULL)) {
in++;
}
// now we are at the first character that is not a vowel or space
for ( ; *in; in++) {
if (strchr("aeiouAEIOU", *in) != NULL) {
// do nothing
} else if (*in == ' ') {
*out++ = *in;
up = 1; // we see a space, so next letter should be upper
} else if (up) {
*out++ = toupper(*in);
up = 0; // we see a letter (or other character), ignore case
} else {
*out++ = *in;
}
}
*out = '\0';
printf("%s\n", str);
}
Well now you have a few examples to study that take a bit of a different approach. See if you understand the logic, and try to make it so that other characters like e.g. ( and ) also delimit words.
One of the problems is that you've got too much code. It iterates through the entire array once to strip out vowels, then again to adjust the case of the first letter of each word. Imagine this is processing data that is measured in Gb. A second pass is unnecessary.
(And, there are standard library functions like isalpha() and toupper() that you should use. Don't write code with "magic numbers".)
It's worth studying a program's 'flow control', without resorting to arbitrary 'continue' statements to affect that flow.
It's also worth starting from scratch with a minimal block of code in main(), then developing your algorithm in a function (or several). Avoid the tendency to have one long, linear program all inside main(). If you can put functionality into 'compartments', each can be developed and tested and forgotten about as the program grows more complex.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// A single pass "compacts" the data (no vowels) while also using some single operations
//tracking changing from one word to the next (first letter to uppercase.)
char *func( char *str ) {
for ( int d = 0, s = 0, up = 0; (str[d] = str[s]) != '\0'; s++)
if( !strchr( " aeiouAEIOU" + !!up, str[d] ) ) {
if( str[d] == ' ' )
up = 1;
else if( up++ < 2 )
up++, str[d] = (char)toupper( (unsigned char)str[d] );
d++; // 'd'estination idx only increments here!
}
return str;
}
int main(void) {
// sample test strings
char *strs[] = {
"I am Iron Man",
" I am Iron Man ",
"Iron Man am I",
" Iron Man am I",
"The man of steel",
" The man of steel",
};
for( size_t i = 0; i < sizeof strs/sizeof strs[0]; i++ )
puts( func( strs[i] ) );
return 0;
}
M Rn Mn
M Rn Mn
Rn Mn M
Rn Mn M
Th Mn F Stl
Th Mn F Stl

I get weird symbols in the output in the terminal

I am trying to make a program that would take a sentence from the user and reverse the order of the words while keeping the special characters ['.','?','!'] at the end.
the problem I'm getting is that I get weird symbols after the last word and the special character.
I am programming using C.
I think it's because the last element printed is not a '\0'.
but I don't know how to fix that.
My code:
#include <ctype.h>
#define N 200
int main()
{
char arr[N] = { 0 };
char* p, * q, mark = 0;
int c;
p = arr;
printf("Enter a sentence: ");
while ((c = getchar()) != '\n' && p < arr + N)
{
if (c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = c;
}
*p = '\0';
printf("Reversal of sentence: ");
while (p >= arr)
{
while (*--p != ' ' && p != arr);
if (p == arr) {q = arr;}
else {q = p + 1;}
while (*q != '\0' && *q != ' ')
{
printf("%c", *q++);
}
if (p >= arr)
{
printf(" ");
}
}
printf("%c", mark);
printf("\n");
return 0;
}
I've fixed the overflow error when reading the sentence by removing the \0 termination. The input string is never used by anything that cares. I've also added a check for End-Of-File.
Next I changed the reversal loop to not underflow and fixed outputing an extra ' ' before the mark.
Last the printf calls can use putchar instead.
#include <ctype.h>
#include <stdio.h>
#define N 200
int main()
{
char arr[N] = { 0 }; // initialization optional, nothing cares
char* p, * q, mark = 0;
int c;
p = arr;
printf("Enter a sentence: ");
while ((c = getchar()) != '\n' && c != EOF && p < arr + N)
{
if (c == '?' || c == '.' || c == '!')
{
mark = c;
break;
}
else
*p++ = c;
}
printf("Reversal of sentence: ");
while (p > arr)
{
while (*--p != ' ' && p != arr);
if (p == arr) {q = arr;}
else {q = p + 1;}
while (*q != '\0' && *q != ' ')
{
putchar(*q++);
}
if (p > arr)
{
putchar(' ');
}
}
putchar(mark);
putchar('\n');
return 0;
}

Counting the vowels and characters in each word of a sentence

I have been trying to figure out how to count the vowels and characters in each word of a sentance.
For example
In hello there sentence
hello : 5 characters, 2 vowels
there : 5 characters, 2 vowels. I have seen the code for doing the same thing for a full sentence. But not word by word.
Below is the coding I've been working on
int main() {
char str[512] = "hello there", word[256];
int i = 0, j = 0, v, h;
str[strlen(str)] = '\0';
/* checking whether the input string is NULL */
if (str[0] == '\0') {
printf("Input string is NULL\n");
return 0;
}
/* printing words in the given string */
while (str[i] != '\0') {
/* ' ' is the separator to split words */
if (str[i] == ' ')
{
for (h = 0; word[h] != '\0'; ++h)
{
if (word[h] == 'a' || word[h] == 'e' || word[h] == 'i' || word[h] == 'o' || word[h] == 'u')++v;
}
printf("\nVowels: %d", v);
word[j] = '\0';
printf("%s\n", word);
j = 0;
}
else
{
word[j++] = str[i];
}
i++;
}
word[j] = '\0';
/* printing last word in the input string */
printf("%s\n", word);
return 0;
}
The input will be all lower case. I'm having a hard time figuring this out.
While running the code I'm not getting the vowels count. I'm able to split the sentence. But vowel counting is not happening.
One fairly simple approach:
#include <stdio.h>
const char* s(int n)
{
return n == 1? "" : "s";
}
void count (const char* str)
{
for (int i = 0;;)
for (int v = 0, w = i;;)
{
int len;
char c = str[i++];
switch (c)
{
case 'a': case 'e': case 'i': case 'o': case 'u':
v++;
default:
continue;
case ' ': case '\t': case '\n': case '\0':
len = i - 1 - w;
printf("'%.*s': %d character%s, %d vowel%s\n", len, str+w, len, s(len), v, s(v));
if (c)
break;
else
return;
}
break;
}
}
int main(void)
{
count("My words with vowels");
return 0;
}
This sounds an awful lot like a homework assignment..
here's some pseudo-code <-- below will NOT run as is. Just to show logic.
int c = 0;
int v = 0;
for (int i = 0; i < lengthOfSentence; i++){
if (stringName[i] == '\0') { //optionally '\n' may be more suitable
return;
}
if (stringName[i] == ' '){
print previousWord // + c, v in whatever format you want
c = 0;
v = 0;
}
if (stringName[i] == vowel) { //you can do this part like in your code
word[v+c] = stringName[i]; //get current char and add to next slot
v++;
}
else {
word[v+c] = stringName[i];
c++;
}
beyond that it's minute details like realizing v+c will give you total word length when printing, etc..
Try this code. it might help you
#include<stdio.h>
int main() {
char str[512] = "hello there", word[256];
int i = 0, j = 0, v=0,h; // you didn't initialize v to 0
str[strlen(str)] = '\0';
/* checking whether the input string is NULL */
if (str[0] == '\0') {
printf("Input string is NULL\n");
return 0;
}
/* printing words in the given string */
while (str[i] != '\0') {
/* ' ' is the separator to split words */
if (str[i] == ' ' ) {
for (h = 0; word[h] != '\0'; h++) {
if (word[h] == 'a' || word[h] == 'e' || word[h] == 'i' || word[h] == 'o' || word[h] == 'u')
v++;
}
printf("%s :", word);
printf(" %d chracters,",strlen(word));
printf(" %d Vowels.\n", v);
j = 0; v=0;
word[j] = '\0';
} else {
word[j++] = str[i];
word[j] = '\0';
}
i++;
}
/* calculating vowels in the last word*/ // when NULL occurs, Wont enter into while loop.
for (h = 0; word[h] != '\0'; h++) {
if (word[h] == 'a' || word[h] == 'e' || word[h] == 'i' || word[h] == 'o' || word[h] == 'u')
v++;
}
printf("%s :", word);
printf(" %d chracters,",strlen(word));
printf(" %d Vowels.\n", v);
return 0;
}
What you can probably do is, you can print the count for the characters and vowels when you encounter a " "(space) and then reset the counters. That way, you can find the characters and vowels for each word of the sentence.
If you understand the logic for doing this throughout a sentence, then you can also do it in single words by simple breaking the sentence into individual word and applying the same logic to each word. You can use the fact that words are separated by a space (or multiple, maybe) to break down the sentence into words.

C for loop to iterate array different from putc

I'm trying to read from a text file and for non printing ascii characters I would like to print out "^" + "G" as an example of the BELL character. Much like the cat -v command of unix. The problem happens in the for loop where I am supposed to store chars until I hit a newline and then print them out. The for loop is printing "G " for ctrl+G and "t " "e " "s " "t " for test.
int readFile(FILE* inputFile) {
char input[5];
char *arrayEnd = &input[5]+1;
int anyChanges = 1;
int iochar = 0;
int i = 0;
//get index of new line
//substring of position until new line
//print substring position to end.
int printedColumns = 0;
//credit Foster Chapter 2
while (( iochar = getc(inputFile) ) != EOF )
{ //Returns 1 if no changes made, return 0 if any changes have been made.
//printf("character --> %c\n",iochar);
if(iochar != '\n') {
//This if statement checks for normal ascii characters.
//If the output is less than 72 it prints it and increments printedColumns.
if (( ' ' <= iochar ) && ( iochar <= 126 ) ) {
if(*(input + i) == *arrayEnd)
{
i = 0;
}
*(input +i) = iochar;
//printf("input array ---> %c\n",input[i]);
//printf("i:%d\n",i);
//printf("iochar:%d\n",iochar);
//putc(*(input+i), stdout);
i++;
}
//This if statement checks for the non-printing characters.
//New line is not included because it is a special case that is accounted for below
if (iochar <= 31) {
if (*(input + i) == *arrayEnd)
{
i = 0;
}
*(input + i) =94;
putc(*(input+i), stdout);
i++;
if(*(input+i)== *arrayEnd)
{
i = 0;
}
*(input + i) = iochar + 64;
putc(*(input+i), stdout);
printf("\n");
i++;
}
int b = 0;
for (b = 0;b<6;b++){
putc(*(input+b),stdout);
}
}//end if != '\n'
}//end while
return anyChanges;
}//end function
This seems to do a lot of what you're looking for:
#include <stdio.h>
static
int readFile(FILE *inputFile)
{
int numChanged = 0;
int iochar = 0;
while ((iochar = getc(inputFile) ) != EOF)
{
if ((' ' <= iochar && iochar <= 126) || iochar == '\n')
putc(iochar, stdout);
else if (iochar < ' ')
{
putc('^', stdout);
putc(iochar + 'A' - 1, stdout);
numChanged++;
}
else
numChanged++;
}
return numChanged;
}
int main(void)
{
printf("Number of changed characters: %d\n", readFile(stdin));
return 0;
}
It worked correctly on its own source code (no characters to change — no tabs in the source), and it seemed to work correctly on its own binary too. Neither output is exciting enough to quote here. Note that it deletes characters from code 0x7F through 0xFF. You can amend that by adjusting the else clause appropriately for whatever rules you choose to specify. The question was silent on the treatment of such characters.
If you need the last 72 characters of a line, then you need to read whole lines; roll in fgets():
#include <stdio.h>
#include <string.h>
static
int readFile(FILE *fp)
{
int numChanged = 0;
char line[4096];
while (fgets(line, sizeof(line), fp) != 0)
{
size_t len = strlen(line);
if (line[len-1] != '\n')
break; // Damn! Line to long
size_t start = 0;
if (len > 72)
start = len - 72;
for (size_t i = start; i < len; i++)
{
/* The next line is only 70 characters long, but this comment should be truncated */
if ((' ' <= line[i] && line[i] <= 126) || line[i] == '\n')
putc(line[i], stdout);
else if (line[i] < ' ')
{
putc('^', stdout);
putc(line[i] + 'A' - 1, stdout);
numChanged++;
}
else
numChanged++;
}
}
return numChanged;
}
int main(void)
{
printf("Number of changed characters: %d\n", readFile(stdin));
return 0;
}
This code, run on its own, carefully kludged source, yields the interesting part:
start = len - 72;
for (size_t i = start; i < len; i++)
{
ine is only 70 characters long, but this comment should be truncated */
if ((' ' <= line[i] && line[i] <= 126) || line[i] == '\n')
putc(line[i], stdout);
else if (line[i] < ' ')
{
You can decide if I've got an off-by-one error in counting the lengths.

Resources