Count number of consonants in a string - c

Another starter question.
int counterConstant;
int x;
for(x = 0; x<20; x++){
if("bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSVWXYZ".IndexOf(tempString[x]) >= 0){
counterConsonant++;
}
}
But I get an error:
"error: member reference base type 'char [42]' is not a structure or union"
Is there another way I could do this?
(I'm doing this inside a for that checks each char on the string.)

There are no objects in C, so there are no "methods" and you can't call IndexOf on a string literal. A string is nothing more than an array of characters in C.
With that in mind, let's see how you can actually loop over the characters of a string:
for (const char *p = tempString; *p != '\0'; ++p) {
/* loop body */
char c = *p; // *p is the current letter
}
This will create a pointer to the first element of the string, and then loop over all of the following characters, if you'd really prefer to use indexes, you could do
for (size_t i = 0, len = strlen(tempString); i < len; ++i) {
char c = tempString[i];
}
As far as checking each letter for consonant-ness, that you can write a helper function for
int is_consonant(char c) {
c = tolower(c); // #include <ctype.h>
if (!isalpha(c)) return 0; // if not a letter, return false
switch (c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return 0;
default:
return 1;
}
}
now back to your loop, use this function to check each character.
int consonant_count = 0; // the =0 is important!
for (const char *p = tempString; *p != '\0'; ++p) {
if (is_consonant(*p)) {
++consonant_count;
}
}
If you don't initialize to 0, the initial value of consonant_count is unpredictable, so make sure you do.

If you are working on C (as it was specified in tags), strchr() method is used to search a char in a string, and strstr() is used to search a string in a string. We will use strchr() here because tempString[x] is a char. Also, don't forget to give your int variable an initial value. Try this code:
int main()
{
int counterConsonant = 0;
int x;
const char* tempString = "12345678901234567890";
for (x = 0; x<20; x++){
if (strchr("bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSVWXYZ", tempString[x]) != NULL){
counterConsonant++;
}
}
return 0;
}

C is a structured procedural language, so it doesn't have member functions/methods like a "true" object-oriented programming language such as C#. You could use a combination of strspn and strcspn like below to count sequences of consonants and non-consonant characters respectively, based on a predefined list of consonant characters:
#include <string.h>
size_t
count_consonants (const char *s)
{
size_t n;
size_t total = 0;
const char *consonants = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
/* While we haven't reached the end of the string,
execute the code in the body of the loop. */
while (*s != '\0')
{
/* Count the number of consonants starting at the current string position. */
n = strspn (s, consonants);
/* Add the number of consonants counted to
the total number of consonants found. */
total += n;
/* Advance the character pointer to the next character
that IS NOT a consonant, based on the number of consonants
stored in `n'. */
s += n;
/* Advance the character pointer to the next character
that IS a consonant (`strcspn' = skip the characters in
`s' that don't appear in `consonants'). */
s += strcspn (s, consonants);
}
return total;
}

char temp[20];
scanf("%s",temp);
int i,j, consonantsCounter=0;
char consonants[]={'b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z','B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','V','W','X','Y','Z'}
for(i=0;i<20;i++){
for(j=0;j<(sizeof consonants) / (sizeof consonants[0]);j++){
if(temp[i]==consonants[j]){
consonantsCounter++;
}
}
}

Related

Use functions to convert string to upper and lowercase in C

This is homework and this is the task I was given:
Prints the string in uppercase and lowercase
Splits the string on the middle and prints the two parts with " - " between
Requirements:
Converting the string to upper and lower case must be done in functions. These functions must return nothing (void) and be called: string_upper, string_lower.
Do not use strlwr or strupr.
Note: The string length is always even.
Expected output (with the string you receive as input):
The string in uppercase is 'ABCDEFGH'
The string in lowercase is 'abcdefgh'
The string split in two is 'abcd - efgh'
I have managed to come up with something that works but it dosent use functions as requiered in the task. How can you do this with funtions?
I have looked around but I cant find any examples of converting strings to upper and lowercase using functions
#include<stdio.h>
#include<string.h>
int main() {
char inputString[100], leftHalf[100], rightHalf[100];
int length, mid, i, k;
/* Read input string from user using gets */
printf("Enter a string\n");
gets(inputString);
/* Find length of string using strlen function */
length = strlen(inputString);
mid = length/2;
/* Copy left half of inputString to leftHalf */
for(i = 0; i < mid; i++) {
leftHalf[i]= inputString[i];
}
leftHalf[i] = '\0';
/* Copy right half of inputString to rightHalf */
for(i = mid, k = 0; i <= length; i++, k++) {
rightHalf[k]= inputString[i];
}
for(i=0;i<=strlen(inputString);i++)
{
if(inputString[i]>=65&&inputString[i]<=90)
inputString[i]=inputString[i]+32;
}
printf("String in Lowercase: %s\n",inputString);
/* To print string in upperCase*/
for(i=0;i<=strlen(inputString);i++)
{
if(inputString[i]>=97&&inputString[i]<=122)
inputString[i]=inputString[i]-32;
}
printf("String in Uppercase: %s\n",inputString);
/* Printing left and right half of string */
//printf("Left half : %s\n",leftHalf);
//printf("Right half : %s\n",rightHalf);
printf("%s-%s",leftHalf, rightHalf);
return 0;
}
To create a function, just remove the code (e.g. the for-loop) to a function. Don't forget to declare auxiliary variables (e.g. int i). Like so
void string_upper (char *inputString)
{
int i;
for(i=0;i<=strlen(inputString);i++)
{
if(inputString[i]>=65&&inputString[i]<=90)
inputString[i]=inputString[i]+32;
}
}
And then in your main code, you call
string_upper (inputString);
instead of the for-loop that was there.
Do the similar for string_lower.
You can just put your code to convert the string to upper and lower case in separate functions. like this.
void string_upper (char* str) {
for(int i=0; i<=strlen(str); i++) {
if(str[i]>=97 && str[i]<=122)
str[i]=str[i]-32;
}
}
void string_lower(char* str) {
//...
}
int main() {
char inputString[100], leftHalf[100], rightHalf[100];
int length, mid, i, k;
//...
/* call function to convert string to upper-case*/
string_upper(inputString);
printf("String in Uppercase: %s\n",inputString);
/* call function to convert string to lower-case */
string_lower(inputString);
printf("String in Lowercase: %s\n",inputString);
//...
return 0;
}
If you're allowed to use tolower() and toupper(), this works:
#include <ctype.h>
// note unsigned char!
void string_upper( unsigned char *str )
{
while ( *str )
{
*str = toupper( *str );
str++;
}
}
string_lower() is left as an exercise for the reader... ;-)

C programming. Function to generate a string of random letters using only arrays and then pointers

Im trying to code a program in C to generate a string containing random letters using only arrays first and then again using pointers. I've looked at many other questions but is not quite what I'm trying to accomplish. I can really use help please.
Function 1- Generates a string with random upper
case letter A-Z with 40 characters.
Function 2- Function to let user enter a string
with random upper case letter and a replacement character.
Function 3- Searches string1 from function 1 and replaces
occurences of any character from string 2 (user entered) with
replacement character.
OUTPUT EX.
String 1- "AABBCCDDEEFFGGHHABCDEFGH"
String 2- "BE"
Replacement char- "3"
Filtered string- AA33CCDD33FFGGHHA3CD3FGH.
This is what I have so far, Im not very good with arrays.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int s1 [41];
srand(time(NULL));
int i;
for (i = 0; i < 41; i++)
{
s1 [i] = rand();
}
return 0;
}
Any help will be appreciated.
Thanks alot.
#include <stdio.h>
#include <stdlib.h>
void rand_str(char* txt, size_t sz)
{
int i=sz-1;
while( i --> 0 )
{
txt[i] = 'A' + rand() % 26;
}
printf("Random Str: %.*s\n", sz+i, txt);
}
void fn2(char* tgt, size_t sz, char* repl )
{
puts("String 2: ");
fgets(tgt, sz, stdin);
puts("Replacement Char: ");
*repl = getchar();
}
void search_replace(char* txt, char* tgt, char repl)
{
while(*tgt != '\0')
{
while ((strchr(txt, *tgt) ? (tgt[strchr(txt, *tgt)-tgt] = repl) : 0) == repl);
tgt++;
}
}
int main(void)
{
char txt[41] = {0};
char tgt[40] = {0};
char repl;
rand_str(txt, sizeof(txt));
fn2(tgt, sizeof(tgt), &repl);
search_replace(txt, tgt, repl);
return !printf("Filtered String: %s\n", txt);
}
Please note that I did not compile any of this code. It might have some typo and/or runtime errors. The concept is correct though and you should understand the code first and not just copy it.
Function 1:
#include <stdlib.h> // Important! rand() function that generate random function is in that library!
//This function returns a pointer of an array (arr). In other words it returns the **address** of the first character of the array.
// Assuming arr is valid!
char* randomString(char* arr){
// This part does not REALLLYY matters it just makes sure the random will truly be random...
time_t t;
srand((unsigned) time(&t)); // Seeds the random function.
//------------------
//Looping the array assigning random letters:
int i = 0;
while(i<SIZE){
arr[i] = 'A'+(rand()%('Z'-'A'+1));// 'A' has a numerical value, we want the range from 'A' to 'Z' to be random. 'Z'-'A' is the range of letters (26) because its a modulu if the modulu was just 'Z'-'A' (26) it wouldnt print Z. 'Z' is the 26th letter, 26%26 is zero, it will not give 'Z' this is why I increased 'Z'-'A' by 1 so the modulu will include 'Z' as random latter.
i = i + 1;
}
arr[i] = 0;// String terminator also called NULL.
return "lol";
}
Function 2:
#include <string.h>
int replace(char* inputString, char* userInput,char replacement ){
/* e.g.
inputString = "ABSDSADASBBBAA";//Generate yourself... (Might want to user function 1)
userInput = "AB"; // You need to do the user input yourself...
replacement = 'D';
*/
int i = 0;
while(i<strlen(inputString)){
int j = 0;
while(j<strlen(userInput)){
if(inputString[i]==userInput[j]){
inputString[i] = replacement;
}
j = j+1;
}
i = i + 1;
}
}
Function 3:
int main(){
// Just use regular IO libraries to get user's input...
// Assuming you did that, I will hard code the values (you need to do the IO e.g. gets())
char str[SIZE];
randomString(str); // Requirement #1 reuse of function 1
char * userInput = "AB"; // You need to do the user input yourself...
char replacement = 'D';// You need to do the user input yourself...
replace(str, userInput, replacement)//Requirement #2
return 0;
}

Reading Both Individual Characters of Strings and the Strings themselves Pointed to by a String Array

In the code below, I'm attempting to pass the string array 'char *wordArray[20]..." into the function above main that is intended to find all strings within wordArray that contain a user-input character, and print each such string. Function "findWords" is defined to expect a constant string array, its length and the user-input character because the array will be read-only. Following examples from the text I'm using, the bottom is a combination of methods for reading individual characters from a pointer to a string, and for reading strings from a pointer array.
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
int arrLength = 0; // Global variable dec. and initialization
void findWords ( const char *c[], int length, char letter ) {
size_t element = 0;
size_t count = 0;
for (element = 0; element < length; element++) {
for (count = 0; c[count] != '\0'; count++) {
if (c[count] == letter) {
printf("%s", c[element]);
}
else {
printf("%s", c[count]);
}
}
count++;
}
return;
} // End function findWords
int main (void) {
{ // Begin Problem 3
// step 1: printf "Problem 3"
puts("Hiya");
// step 2: create a string array of 3 pointers to strings containing at this point, random
words.
const char *wordArray[3] = { "cake", "foxtrot", "verimax" };
char usrInp; // Holds user-input letter.
// step 3: "Input a letter from the user."
// This do...while loop repeats until the user has entered either a lower- or uppercase
letter.
do {
puts("Please enter one lowercase letter - any you'd like\n"); // One string argument
calls for output function puts(); rather than printf();
usrInp = tolower ( getchar() );
} while ( isalpha (usrInp) == 0 );
findWords( wordArray, arrLength, usrInp );
} // End Problem 3
} // End function main
at findWords :
for (element = 0; element < length; element++) {
for (count = 0; c[element][count] != '\0'; count++) {
if (c[element][count] == letter) {
printf("%s\n", c[element]);
break;
}
}
}
at main :
arrLength = sizeof(wordArray)/sizeof(*wordArray);//arrLength = 3;
findWords( wordArray, arrLength, usrInp );
c[count] is char* which means you cannot compare it to a char. this pointer just holds the address to your current string. you need to traverse that string in order to check for letter.
In your code you need to change:
if (c[element][count] == letter)

C program, Reversing an array

I am writing C program that reads input from the standard input a line of characters.Then output the line of characters in reverse order.
it doesn't print reversed array, instead it prints the regular array.
Can anyone help me?
What am I doing wrong?
main()
{
int count;
int MAX_SIZE = 20;
char c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
while(c != EOF)
{
count = 0;
c = getchar();
arr[count++] = c;
getReverse(revArr, arr);
printf("%s", revArr);
if (c == '\n')
{
printf("\n");
count = 0;
}
}
}
void getReverse(char dest[], char src[])
{
int i, j, n = sizeof(src);
for (i = n - 1, j = 0; i >= 0; i--)
{
j = 0;
dest[j] = src[i];
j++;
}
}
You have quite a few problems in there. The first is that there is no prototype in scope for getReverse() when you use it in main(). You should either provide a prototype or just move getReverse() to above main() so that main() knows about it.
The second is the fact that you're trying to reverse the string after every character being entered, and that your input method is not quite right (it checks an indeterminate c before ever getting a character). It would be better as something like this:
count = 0;
c = getchar();
while (c != EOF) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
That will get you a proper C string albeit one with a newline on the end, and even possibly a multi-line string, which doesn't match your specs ("reads input from the standard input a line of characters"). If you want a newline or file-end to terminate input, you can use this instead:
count = 0;
c = getchar();
while ((c != '\n') && (c != EOF)) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
And, on top of that, c should actually be an int, not a char, because it has to be able to store every possible character plus the EOF marker.
Your getReverse() function also has problems, mainly due to the fact it's not putting an end-string marker at the end of the array but also because it uses the wrong size (sizeof rather than strlen) and because it appears to re-initialise j every time through the loop. In any case, it can be greatly simplified:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0) {
dest[j] = src[i];
j++;
i--;
}
dest[j] = '\0';
}
or, once you're a proficient coder:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0)
dest[j++] = src[i--];
dest[j] = '\0';
}
If you need a main program which gives you reversed characters for each line, you can do that with something like this:
int main (void) {
int count;
int MAX_SIZE = 20;
int c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
c = getchar();
count = 0;
while(c != EOF) {
if (c != '\n') {
arr[count++] = c;
c = getchar();
continue;
}
arr[count] = '\0';
getReverse(revArr, arr);
printf("'%s' => '%s'\n", arr, revArr);
count = 0;
c = getchar();
}
return 0;
}
which, on a sample run, shows:
pax> ./testprog
hello
'hello' => 'olleh'
goodbye
'goodbye' => 'eybdoog'
a man a plan a canal panama
'a man a plan a canal panama' => 'amanap lanac a nalp a nam a'
Your 'count' variable goes to 0 every time the while loop runs.
Count is initialised to 0 everytime the loop is entered
you are sending the array with each character for reversal which is not a very bright thing to do but won't create problems. Rather, first store all the characters in the array and send it once to the getreverse function after the array is complete.
sizeof(src) will not give the number of characters. How about you send i after the loop was terminated in main as a parameter too. Ofcourse there are many ways and various function but since it seems like you are in the initial stages, you can try up strlen and other such functions.
you have initialised j to 0 in the for loop but again, specifying it INSIDE the loop will initialise the value everytime its run from the top hence j ends up not incrmenting. So remore the j=0 and i=0 from INSIDE the loop since you only need to get it initialised once.
check this out
#include <stdio.h>
#include <ctype.h>
void getReverse(char dest[], char src[], int count);
int main()
{
// *always* initialize variables
int count = 0;
const int MaxLen = 20; // max length string, leave upper case names for MACROS
const int MaxSize = MaxLen + 1; // add one for ending \0
int c = '\0';
char arr[MaxSize] = {0};
char revArr[MaxSize] = {0};
// first collect characters to be reversed
// note that input is buffered so user could enter more than MAX_SIZE
do
{
c = fgetc(stdin);
if ( c != EOF && (isalpha(c) || isdigit(c))) // only consider "proper" characters
{
arr[count++] = (char)c;
}
}
while(c != EOF && c != '\n' && count < MaxLen); // EOF or Newline or MaxLen
getReverse( revArr, arr, count );
printf("%s\n", revArr);
return 0;
}
void getReverse(char dest[], char src[], int count)
{
int i = count - 1;
int j = 0;
while ( i > -1 )
{
dest[j++] = src[i--];
}
}
Dealing with strings is a rich source of bugs in C, because even simple operations like copying and modifying require thinking about issues of allocation and storage. This problem though can be simplified considerably by thinking of the input and output not as strings but as streams of characters, and relying on recursion and local storage to handle all allocation.
The following is a complete program that will read one line of standard input and print its reverse to standard output, with the length of the input limited only by the growth of the stack:
int florb (int c) { return c == '\n' ? c : putchar(florb(getchar())), c; }
main() { florb('-'); }
..or check this
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
char *my_rev(const char *source);
int main(void)
{
char *stringA;
stringA = malloc(MAX); /* memory allocation for 100 characters */
if(stringA == NULL) /* if malloc returns NULL error msg is printed and program exits */
{
fprintf(stdout, "Out of memory error\n");
exit(1);
}
else
{
fprintf(stdout, "Type a string:\n");
fgets(stringA, MAX, stdin);
my_rev(stringA);
}
return 0;
}
char *my_rev(const char *source) /* const makes sure that function does not modify the value pointed to by source pointer */
{
int len = 0; /* first function calculates the length of the string */
while(*source != '\n') /* fgets preserves terminating newline, that's why \n is used instead of \0 */
{
len++;
*source++;
}
len--; /* length calculation includes newline, so length is subtracted by one */
*source--; /* pointer moved to point to last character instead of \n */
int b;
for(b = len; b >= 0; b--) /* for loop prints string in reverse order */
{
fprintf(stdout, "%c", *source);
len--;
*source--;
}
return;
}
Output looks like this:
Type a string:
writing about C programming
gnimmargorp C tuoba gnitirw

Finding the number of two consecutive vowels in a string does not work

When two vowels come one after another then the count should increment.But i dont know why its incrementing it more than that.
#include<stdio.h>
#include<conio.h>
void main(void)
{
int i,j,count=0;
char string[80];
printf("Enter a string:\n");
gets(string);
for(i=0; ;i++)
{
if(string[i]=='\0')
break;
if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
if(string[i+1]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
count++;
}
}
printf("%d",count);
getch();
}
Looks like you have a typo here, your code:
if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
if(string[i+1]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
count++;
}
Notice the second if statement there, everything except the first condition is checking string[i] instead of string[i+1]. So if you have 'A' in string[i], then this will increment count no matter what is in string[i+1].
You want:
if(string[i]=='a'||string[i]=='A'||string[i]=='e'||string[i]=='E'||string[i]=='i'||string[i]=='I'||string[i]=='o'||string[i]=='O'||string[i]=='u'||string[i]=='U')
{
if(string[i+1]=='a'||string[i+1]=='A'||string[i+1]=='e'||string[i+1]=='E'||string[i+1]=='i'||string[i+1]=='I'||string[i+1]=='o'||string[i+1]=='O'||string[i+1]=='u'||string[i+1]=='U')
count++;
}
I also recommend you look up the function tolower which will lower-case a character, meaning you need to do less comparisons which will make this code much easier to read and maintain. Also you might consider using a switch or any array hereand probably writing a helper function.
I guess I just can't stand this code as it is, here's a better version:
int is_vowel(char ch)
{
switch (tolower(ch))
{
case 'a': case 'e': case 'i': case 'o': case 'u':
return 1;
default:
return 0;
}
}
And then make your if statement:
if (is_vowel(string[i]) && is_vowel(string[i+1]))
count++;
See, much cleaner and easier to read, don't you think?
You also have a buffer overflow:
gets(string);
And the following is bad style:
for(i=0; ;i++)
{
if(string[i]=='\0')
break;
should be
for(i=0; string[i]!='\0';i++)
For once, be as lazy as you can. If you have to repeat a portion of code, ask yourself if you can't do it without repeating.
I would have gone for that :
#include <stdio.h>
#include <string.h>
#include <ctype.h>
const size_t MAX_LENGTH = 100;
//Counts the occurrences of two consecutive same characters
//in a string, without case
size_t cnt_doubled(char const * const str, int c) {
size_t ret = 0;
//A pointer browses the string until terminating char and
//increments ret if the pointed char is the one seeked
//two chars in a row
for(char const *p = str ; *p != '\0' ; ++p) {
ret += tolower(*p) == tolower(c) && tolower(*(p+1)) == tolower(c);
}
return ret;
}
//Explicit...
size_t cnt_doubled_vowels(char *str) {
char const *vowels = "aeiouy";
//A pointer browses the vowels and takes into account
//the occurrences in the string of every char pointed
size_t n_vowels = 0;
for(char const *p = vowels ; *p != '\0' ; ++p) {
n_vowels += cnt_doubled(str, *p);
}
return n_vowels;
}
int main(void) {
//fgets returns a string terminated by a newline char (before
//terminating char of course) but in your case it doesn't
//matter
char string[MAX_LENGTH] = "";
fgets(string, MAX_LENGTH, stdin);
printf("N : %d", cnt_doubled_vowels(string));
return 0;
}

Resources