Counting number of words which starts with a given letter - c

I am a beginner and am making a program for counting how many words start with a given letter, I wrote a program that counts how many words starts with the letter A but can't make it to find using given letter - I tried making another variable ch and asking it from the user and verifying if *p == "ch" but it does not work
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 200 };
char sentence[N];
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
size_t n = 0;
for ( const char *p = sentence; *p; p += strcspn( p, " \t" ) )
{
p += strspn( p, " \t" );
if ( *p == 'A' ) ++n;
}
printf("No. of A in string \"%s\" is %zu\n", sentence, n );
return 0;
}
The code that I tried:
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 200 };
char sentence[N];
char ch;
printf("Enter one char");
scanf("%c", &ch);
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
size_t n = 0;
for ( const char *p = sentence; *p; p += strcspn( p, " \t" ) )
{
p += strspn( p, " \t" );
if ( *p == ch ) ++n;
}
printf("No. of A in string \"%s\" is %zu\n", sentence, n );
return 0;
}

The problem is a classic one: scanf("%c", &ch); reads a single byte and leaves the newline in the stdin buffer, hence fgets( sentence, N, stdin ); reads the rest of the input line without waiting for further user input.
You should read the rest of the input line after the scanf() with:
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;

You're making it much too complicated. I suggest something like this:
#include <stdio.h>
#include <string.h>
int isBlankSpace (char ch) {
return (ch == ' ' || ch == '\t' || ch == '\n');
}
int main(void) {
char sent[200], ch;
printf("Enter a char: ");
ch = getchar();
getchar(); //gets newline character
printf("Enter a sentence: " );
fgets(sent,200,stdin);
int count = 0, i=0;
while (i < strlen(sent)) {
while (isBlankSpace(sent[i])) i++; //successive blank spaces
if ((i==0 || isBlankSpace(sent[i-1])) && sent[i] == ch) count++;
i++;
}
printf("No. of words starting with %c's in the "\
"string \"%s\" is %d\n", ch, sent, count);
return 0;
}

Related

how to change a word in a string by its number?

I have this assignment:
Replace the numbered word in the sentence with three characters: ???
The problem is I can't replace the whole word by its number, my program changes only 3 first characters.
Here is my code:
#include <stdio.h>
#include <string.h>
int main() {
char sentence[100];
int word_number;
int pos;
int i;
printf("Enter sentence: ");
fgets(sentence, 100, stdin);
printf("Enter word number: ");
scanf("%d", &word_number);
pos = 0;
for (i = 0; i < strlen(sentence); i++) {
if (sentence[i] == ' ') {
word_number--;
}
if (word_number == 1) {
pos = i;
break;
}
}
// Update the sentence
sentence[pos] = '?';
sentence[pos + 1] = '?';
sentence[pos + 2] = '?';
printf("Result sentence: %s\n", sentence);
return 0;
}
There are multiple issues in the code:
Your approach only works if the word to be replaced has exactly 3 letters. For longer or shorter words, you need to move the contents of the remainder of the string.
Another restriction in your code is you assume that words a separated by a single space, which may of may not be explicitly stated in the assignment.
Similarly, you assume the n-th word is followed by a space, which may not be the case if the word is the last one in the sentence.
you should check the return values of fgets() and scanf() to detect invalid or missing input.
Here is a modified version.
#include <stdio.h>
#include <string.h>
int is_sep(char cc) {
// separators are space, newline and the null byte
return (cc == ' ' || cc == '\n' || cc == '\0');
// you could also accept punctuation as word separators:
//return strchr(" \t\n.,:;?!'`"##$%^&*()[]{}<>/`~+=|", cc);
}
int main() {
char sentence[200];
int word_number;
printf("Enter sentence: ");
// read a sentence, allow for 2 extra bytes to insert replacement
if (!fgets(sentence, sizeof(sentence) - 2, stdin))
return 1;
printf("Enter word number: ");
if (scanf("%d", &word_number) != 1)
return 1;
int len = strlen(sentence);
int start = 0;
int wn = 1;
char last = ' ';
for (int i = 0;; i++) {
char cc = sentence[i];
if (is_sep(cc)) {
if (!is_sep(last)) {
/* end of word */
if (wn == word_number) {
// replace this word with `???`
memmove(sentence + start + 3, sentence + i, len + 1 - i);
memcpy(sentence + start, "???", 3);
break;
}
wn++;
}
} else {
if (is_sep(last)) {
/* start of a word */
start = i;
}
}
last = cc;
if (cc == '\0')
break;
}
printf("Result sentence: %s\n", sentence);
return 0;
}
I’m not sure I’d try to do this in-place. For small data, it doesn’t hurt to just create a new buffer, even if it is just a temporary.
But, since we are posting solutions, here’s a single-pass version:
#include <iso646.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void replace_nth_word_with( char * dest, int n, const char * src, const char * word )
{
char last = ' ';
while (*src) // For each character in src:
if ((*src != ' ') and (last == ' ') and !n--) // If we found a word-begin AND it is the Nth word:
{ //
for (size_t k = 0; word[k]; k++) // Copy the new word to dest
*dest++ = word[k]; //
while (*src and (*src != ' ')) ++src; // Skip the old word in src
} //
else // Otherwise just copy the character over
last = *dest++ = *src++; //
*dest = '\0'; // End of string
}
void ask_string( const char * prompt, char * s, size_t n )
{
printf( "%s", prompt );
fgets( s, (int)n, stdin );
char * p = strpbrk( s, "\n\r" );
if (p) *p = '\0';
}
void ask_int( const char * prompt, int * n )
{
char s[20];
printf( "%s", prompt );
fgets( s, sizeof s, stdin );
*n = strtol( s, NULL, 10 );
// It hurts to write this without error checking, LOL
}
int main(void)
{
char sentence[1000];
ask_string( "Sentence? ", sentence, sizeof sentence );
int word_number;
ask_int( "Word number (counting from 1)? ", &word_number );
char new_word[100];
ask_string( "New word? ", new_word, sizeof new_word );
char new_sentence[sizeof sentence + sizeof new_word];
replace_nth_word_with( new_sentence, word_number-1, sentence, new_word );
printf( "\"%s\"\n", new_sentence );
return 0;
}

I need a program in C, which finds all the words that start and end with the same letter

I'm trying to make a program that counts all the words that start and end with the same character. in C
It tells me correctly which is the first and which is the last, I don't know how to make it show me the ones that are equal.
#include <stdio.h>
#include <string.h>
int main()
{
char s[50];
printf("Introdu propozitia : ");
gets(s);
int i, j = 0;
// Traversing the Character array
for (i = 0; i < strlen(s); i++) {
// To store first character of
// String if it is not a
// whitespace.
if (i == 0 && s[i] != ' ') {
printf("%c ", s[i]);
}
if (s[i] == ' ')
printf("%c", s[i -1]);
// To check whether Character
// is first character of
// word and if yes store it.
else if (i > 0 && s[i - 1] == ' ') {
printf(" %c ", s[i]);
}
else if (i>0 && s[i] == ' ')
printf("%c", s[i -1]);
if(s[i]==s[i-1])
Total ++;
printf("\n Sunt : %d", Total);
}
return 0;
}
For starters the function gets is unsafe and is not supported by the C Standard. Instead use either scanf or fgtes.
This if statement
if(s[i]==s[i-1])
Total ++;
does not make sense.
Using the function strlen in the for loop is inefficient and redundant.
To find starts and ends of words in a string you can use standard string functions strspn and strcspn.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
int main( void )
{
char s[50];
printf( "Introdu propozitia : " );
fgets( s, sizeof( s ), stdin );
size_t count = 0;
const char *delim = " \t\n";
for ( const char *p = s; *p; )
{
p += strspn( p, delim );
size_t n = strcspn( p, delim );
if (n != 0 && p[0] == p[n - 1])
{
++count;
}
p += n;
}
printf( "\nSunt : %zu\n", count );
}
Its output might look like
Introdu propozitia : 123454321 2345432 34543 454 5
Sunt : 5
If you want to output the words that satisfy the condition then add one statement in the if statement of the program
if (n != 0 && p[0] == p[n - 1])
{
++count;
printf( "%.*s\n", ( int )n, p );
}

c - reverse string comparison (palindrome)

I want to check an entered text for a palindrome.
However, when I enter a palindrome, I always get that it is NOT a palindrome. Have I done something wrong with the stored linefeed character?
#include<stdio.h>
#include<string.h>
int main()
{
char text[256], reverse[256];
int i, j;
printf("Type a text: ");
fgets(text, 255, stdin);
j = strlen(text)-1;
for (i=0; i<=j; ++i)
{
if(text[i] >= 'A' && text[i] <= 'Z')
{
text[i] += 32;
}
if(text[i] == '\n')
{
text[i] = i - 1;
}
}
i = strlen(text)-1;
for (i = i, j = 0 ;i >= 0 ; --i, ++j)
{
reverse[j] = text[i];
}
printf("Text: %s\n", text);
printf("Reverse: %s\n", reverse);
if (strcmp(text, reverse) == 0)
{
printf("The entered text \"%s\" is a palindrome!\n", text);
}
else
{
printf("The entered text \"%s\" is NOT a palindrome!\n", text);
}
}
Yes, your treatment of the linefeed character is wrong.
You replaced the linefeed character with some other (or maybe same) character, but it means there will be an extra character in the string and the extra character will prevent the string from being jugded as a palindrome.
You should replace the linefeed character to '\0' (NUL character), which is used as string termination mark in C.
This if statement
if(text[i] == '\n')
{
text[i] = i - 1;
}
does not make a sense. Moreover as the new line character '\n' is a single character in an entered string then keeping it within the string will result that the string is not a palindrome.
You need to substitute it for the zero character '\0'.
And the array reverse does not contain a string after this loop
for (i = i, j = 0 ;i >= 0 ; --i, ++j)
{
reverse[j] = text[i];
}
Also using the function strlen is redundant and inefficient.
The program can look the following way.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char text[256], reverse[256];
printf( "Type a text: " );
fgets( text, sizeof( text ), stdin );
size_t n = 0;
while ( text[n] != '\0' )
{
if ( text[n] == '\n' )
{
text[n] = '\0';
}
else
{
text[n] = tolower( ( unsigned char )text[n] );
++n;
}
}
reverse[n] = '\0';
for ( size_t i = 0; n-- != 0; i++ )
{
reverse[n] = text[i];
}
printf( "Text: \"%s\"\n", text );
printf( "Reverse: \"%s\"\n", reverse);
if ( strcmp( text, reverse ) == 0 )
{
printf( "The entered text \"%s\" is a palindrome!\n", text );
}
else
{
printf( "The entered text \"%s\" is NOT a palindrome!\n", text );
}
return 0;
}
The program output might look like
Type a text: ABC cba
Text: "abc cba"
Reverse: "abc cba"
The entered text "abc cba" is a palindrome!
In general the used by you approach when you need an auxiliary array and when the source string is being changed is not good.
Your could write a simple function as it is shown in this demonstrative program.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int is_palindrome( const char *s )
{
size_t n = strlen( s );
size_t i = 0;
while ( i < n / 2 && tolower( ( unsigned char )s[i] ) ==
tolower( ( unsigned char )s[n -i -1] ) )
{
++i;
}
return i == n / 2;
}
int main(void)
{
char text[256];
printf( "Type a text: " );
fgets( text, sizeof( text ), stdin );
text[ strcspn( text, "\n" ) ] = '\0';
printf( "Text: \"%s\"\n", text );
if ( is_palindrome( text ) )
{
printf( "The entered text \"%s\" is a palindrome!\n", text );
}
else
{
printf( "The entered text \"%s\" is NOT a palindrome!\n", text );
}
return 0;
}
The program output might look like
Type a text: ABC cba
Text: "ABC cba"
The entered text "ABC cba" is a palindrome!
As you see the original string was not changed except the new line character '\n' was substituted for the zero character '\0'.

Counting number of words which starts with 'A' letter? - C

I just started learning C after Java, so it's a little bit confusing to me. I tried to write a program with idea of counting the numbers of words which start with 'A' letter. The problem is that it only reads the first word I enter and ignore the rest of the sentence. Can somebody help me with this one? I would appreciate it.
#include <stdio.h>
#include <string.h>
void main() {
char sentence[200];
int i;
int counter = 0;
printf("Enter sentence: ");
scanf("%s", &sentence);
for (i = 0; sentence[i] != 0, sentence[i] != ' '; i++){
if (sentence[i] == 'A') {
counter = counter +1;
}
}
printf("No. of A in string %s > %d\n", sentence, counter);
return 0;
}
We beginners should help each other.:)
Here you are.
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 200 };
char sentence[N];
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
size_t n = 0;
for ( const char *p = sentence; *p; p += strcspn( p, " \t" ) )
{
p += strspn( p, " \t" );
if ( *p == 'A' ) ++n;
}
printf("No. of A in string \"%s\" is %zu\n", sentence, n );
return 0;
}
The program output might look like
Enter sentence: Any word that starts with A
No. of A in string "Any word that starts with A" is 2
Also it is better to substitute the string literal " \t" for a named variable.
For example
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 200 };
char sentence[N];
char c = 'A';
const char *blank = " \t";
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
size_t n = 0;
for ( const char *p = sentence; *p; p += strcspn( p, blank ) )
{
p += strspn( p, blank );
if ( *p == c ) ++n;
}
printf("No. of %c in string \"%s\" is %zu\n", c, sentence, n );
return 0;
}
You could write a separate function that does the task. The function declaration will look like
size_t count_words_start_with( const char *s, char c );
Here is a demonstrative program.
#include <stdio.h>
#include <string.h>
size_t count_words_start_with( const char *s, char c )
{
const char *blank = " \t";
size_t n = 0;
for ( const char *p = s; *p; p += strcspn( p, blank ) )
{
p += strspn( p, blank );
if ( *p == c ) ++n;
}
return n;
}
int main(void)
{
enum { N = 200 };
char sentence[N];
char c = 'A';
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
printf("No. of %c in string \"%s\" is %zu\n",
c, sentence, count_words_start_with( sentence, c ) );
return 0;
}
Take into account that my answers almost always are the best answers.:)
Scan with strstr the string for words starting with "A" after empty space, then for the first word in the string:
...
fgets(sentence, sizeof(sentence), stdin);
int count = 0;
const char *tmp = sentence;
while(tmp = strstr(tmp, " A")) {
count++;
tmp++;
}
if (sentence[0] == 'A') count++;
...

C source code to change first letters of words from lowercase to uppercase in a string

I have a C source code, but I have a problem with it. I want to convert the first letters of words in a string that I enter from lowercase to uppercase, but it changes all letters to uppercase. Can you help me solve this?
#include <stdio.h>
#include <ctype.h>
#include <conio.h>
void main()
{
char sentence[100];
int count, ch, i;
int str[32];
printf("Enter a sentence \n");
for (i = 0; (sentence[i] = getchar()) != '\n'; i++)
{
;
}
sentence[i] = '\0';
/* shows the number of chars accepted in a sentence */
count = i;
printf("The given sentence is : %s", sentence);
printf("\n Case changed sentence is: ");
for (i = 0; i < count; i++)
{
ch = islower(sentence[i])? toupper(sentence[i]) : tolower(sentence[i]);
putchar(ch);
}
getch();
}
e.g.
Input: welcome to Sharif university
Desired output: Welcome To Sharif University
Actual output: WELCOME TO SHARIF UNIVERSITY
You must have check if the current char is a space and then only use toupper on the character after the space.
ch = ' ';
for (i = 0; i < count; i++)
{
ch = isspace(ch) ? toupper(sentence[i]) : tolower(sentence[i]);
putchar(ch);
}
Try the following code.:)
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
do
{
while ( isblank( ( unsigned char )*p ) ) ++p;
if ( islower( ( unsigned char )*p ) ) *p = toupper( *p );
while ( *p && !isblank( ( unsigned char )*p ) ) ++p;
} while ( *p );
printf( "\nCase changed sentence is: %s", sentence );
return 0;
}
The output is
The given sentence is : welcome to Sharif university
Case changed sentence is: Welcome To Sharif University
If yor compiler does not support function isblank then you can substitute it for isspace
It seems that a more correct approach will be to use only isalpha because in general case after a blank there can be for example a digit or punctuation
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
do
{
while ( *p && !isalpha( ( unsigned char )*p ) ) ++p;
if ( islower( ( unsigned char )*p ) ) *p = toupper( *p );
while ( isalpha( ( unsigned char )*p ) ) ++p;
} while ( *p );
printf( "\nCase changed sentence is: %s", sentence );
return 0;
}
If you do not want to change the original string then the code will look like
#include <stdio.h>
#include <ctype.h>
#define N 100
int main( void )
{
char sentence[N];
char *p = sentence;
printf( "Enter a sentence: " );
if ( !fgets( sentence, sizeof( sentence ), stdin ) ) sentence[0] = '\0';
printf( "\nThe given sentence is : %s", sentence );
printf( "\nCase changed sentence is: " );
do
{
while ( *p && !isalpha( ( unsigned char )*p ) ) putchar( *p++ );
if ( islower( ( unsigned char )*p ) ) putchar( toupper( *p++ ) );
while ( isalpha( ( unsigned char )*p ) ) putchar( *p++ );
} while ( *p );
return 0;
}
You need to check for characters which have a space preceding them and upper case them. You also need to check for the first character which is a special case as it does not have a space preceding it.
#include <string.h>
#include <stdio.h>
int main (void)
{
char str[] = "this is a test string";
int loop;
for (loop=-1; loop<(int) strlen(str)-1; loop++)
{
// Possible upper case required?
if (loop < 0 || str[loop]==' ')
if (str[loop+1] >= 'a' && str[loop+1] <='z')
str[loop+1] = (str[loop+1] - 'a') + 'A';
}
printf ("string is : %s\n", str);
return 0;
}
Output:
string is : This Is A Test String

Resources