Counting number of words which starts with 'A' letter? - C - 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++;
...

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

Counting number of words which starts with a given letter

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

Reversing string with char aaryas

I'm learning C now, and i have one question in my program.
I need to reverse string like
I like dogs -> I ekil sgod
I wrote this code
char end[MAX_LEN];
char beg[MAX_LEN];
char* piece = strtok(str, " ");
strcpy(end, piece);
strcpy(beg, piece);
char* pbeg = beg;
char* prev = piece;
int n = strlen(piece)-1;
i = 0;
int n = 0;
while (piece != NULL) {
//printf("\n%s", piece);
while (piece[i] != '\0') {
*(prev + n -i ) = *(pbeg + i);
i++;
}
printf("\n%s", piece);
piece = strtok(NULL, " ");
strcpy(beg, piece); // also in this moment in debugging i saw this error ***Exception thrown at 0x7CBAF7B3 (ucrtbased.dll) in лаб131.exe: 0xC0000005: Access violation reading location 0x00000000.***
}
But it returns only the first lexeme reversed.
You are getting an exception because you are not checking whether the pointer piece is equal to NULL when you are using it in the call of strcpy
piece = strtok(NULL, " ");
strcpy(beg, piece);
Also within the while loop you forgot to reset the variables i and n and the pointer prev.
To use the function strtok is a bad idea because the source string can contain adjacent space characters that should be preserved in the result string. Also you have too many arrays and pointers that only confuse readers of the code.
Here is a demonstration program that shows how the task can be easy done.
#include <stdio.h>
#include <string.h>
void reverse_n( char s[], size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n-i-1];
s[n-i-1] = c;
}
}
int main(void)
{
char input[] = "I like dogs";
const char *separator = " \t";
for ( char *p = input; *p; )
{
p += strspn( p, separator );
char *q = p;
p += strcspn( p, separator );
reverse_n( q, p - q );
}
puts( input );
return 0;
}
The program output is
I ekil sgod

How to Reverse a sentence word by word?

I was trying to reverse a sentence word by word. (how are you -> you are how) First of all I create a char sentence and reverse and temp. Sentence given by user to reverse. Temp catches the word to change the location in the sentence.Then I use strcat to concatenate each word. Here is the problem. I can find the word which is end of the sent(takes input) but when I'm trying to concatenate to reverse, it add this word to sentence and an error occurs. What's the problem?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* subs(char* temp, char* src, int start, int end);
int main() {
char sent[15]; //input sentence
char rev[15]; // output sentence
char *temp=(char*)calloc(1,sizeof(char)); //for the word
scanf(" %[^\n]%*c", &sent); // takin' input
int i, end, start;
i = strlen(sent);
//find the beggining and ending of the indexes of the word in sentence
while (i > 0) {
while (sent[i] == ' ') {
i--;
}
end = i-1;
while (sent[i] != ' ') {
i--;
}
start = i + 1;
//add the word to temp and concatenate to reverse
temp=subs(temp, sent, start, end);
strncat(rev, temp,end-start+3);
}
rev[strlen(sent)] = '\0';
printf("%s", rev);
return 0;
}
char* subs(char* temp, char* src, int start, int end) {
int i = 0, control;
// resize the temp for the wırd
temp = (char*)realloc(temp,end-start+3);
for (; i < (end - start) + 1; i++) {
control = (start + i);
temp[i] = src[control];
}
//adding blank and null character to end of the word.
temp[i] = ' ';
temp[++i] = '\0';
return temp;
}
I will just copy my good answer from this question that was not yet closed Reverse a string without strtok in C
. So I can not use this reference to close your question as a duplicate.
A standard approach is to reverse each word within a string and then to reverse the whole string.
The standard C function strtok is not appropriate in this case. Instead use the standard C functions strspn and strcspn.
Here you are.
#include <stdio.h>
#include <string.h>
static char * reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[ i ];
s[ i ] = s[ n - i - 1 ];
s[ n - i - 1 ] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *p = s;
while ( *p )
{
p += strspn( p, delim );
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
reverse( q, p - q );
}
}
return reverse( s, p - s );
}
int main(void)
{
char s[] = "5 60 +";
puts( s );
puts( reverse_by_words( s ) );
return 0;
}
The program output is
5 60 +
+ 60 5
If you want to keep leading and trailing spaces as they were in the original string then the functions can look the following way
#include <stdio.h>
#include <string.h>
static char *reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i -1 ];
s[n - i - 1] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *first = s, *last = s;
for ( char *p = s; *p; )
{
p += strspn( p, delim );
if ( last == s ) first = last = p;
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
last = p;
reverse( q, p - q );
}
}
reverse( first, last - first );
return s;
}
int main(void)
{
char s[] = "\t\t\t5 60 +";
printf( "\"%s\"\n", s );
printf( "\"%s\"\n", reverse_by_words( s ) );
return 0;
}
The program output is
" 5 60 +"
" + 60 5"

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