I am trying to create a program that removes the vowels from a sentence. However, my program keeps failing because it keeps printing zero byte in the string. Would anyone be able to show me where I am going wrong?
#include <stdio.h>
int remove_all_vowels(int character);
int main(void) {
int character = getchar();
while (character != EOF && character != '\0') {
int new_character = remove_all_vowels(character);
putchar(new_character);
character = getchar();
}
return 0;
}
int remove_all_vowels(int character) {
if (character == 'a' || character == 'e' || character == 'i' || character
== 'o' || character == 'u') {
return 0;
} else {
return character;
}
}
Your issue (outputting null characters) comes from the fact that you unconditionally putchar(3) the result of remove_all_vowels, which returns 0 (null character) when given character is a vowel.
To replace vowels with spaces:
You can simply change return 0; in remove_all_vowels to return ' ';
To completely remove vowels:
I would suggest having a function just to help you check against vowels rather than having it act like a transformation over a char, which is really pythonest.
Example of code:
int is_vowel(int character) {
return (
character == 'a' || character == 'e' || character == 'i'
|| character == 'o' || character == 'u'
);
}
// Then, in your main...
...
if (!is_vowel(character))
putchar(character);
your program works fine here
https://www.onlinegdb.com/online_c_compiler
Can give a screenshot whats the problem of your compiler?
#include <stdio.h>
#include <string.h>
int check_vowel(char);
int main()
{
char s[100], t[100];
int c, d = 0;
printf("Enter a string to delete vowels\n");
gets(s);
for(c = 0; s[c] != '\0'; c++) {
if(check_vowel(s[c]) == 0) { // If not a vowel
t[d] = s[c];
d++;
}
}
t[d] = '\0';
strcpy(s, t); // We are changing initial string. This is optional.
printf("String after deleting vowels: %s\n", s);
return 0;
}
int check_vowel(char ch)
{
if (ch == 'a' || ch == 'A' || ch == 'e' || ch == 'E' || ch == 'i' || ch == 'I' || ch =='o' || ch=='O' || ch == 'u' || ch == 'U')
return 1;
else
return 0;
}
Related
I am getting an int of the entire string s for 'letter', the conditions in my 'if' statement seem to not be reading properly - is my syntax incorrect?
I get user input:
string s = get_string("Text here: ");
the function is as follows:
int letter_count(string s)
{
int i =0;
int len = strlen(s);
int letter = 0;
while(i < len)
{
if (s[i] != '\0' || s[i] != '.' || s[i] != ',' || s[i] != '!' || s[i] != '?')
{
letter++;
}
i++;
}
return letter;
}
then call the function:
int letter = letter_count(s);
printf("letter Count: %i\n", letter);
Try changing the OR operator with the AND
if (s[i] != '\0' || s[i] != '.' || s[i] != ',' || s[i] != '!' || s[i] != '?')
is ALWAYS true. Because any character is either not "." or not ",". Which letter would you expect to be both?
You want to check whether the current letter is "not ." AND "not ," AND "not !".
I.e.
if (s[i] != '\0' && s[i] != '.' && s[i] != ',' && s[i] != '!' && s[i] != '?')
Almost correct, you have to change the type of the argument to char*, there is no string type on the default libraries. (Documentation of string library).
Working example with the modifications:
#include <stdio.h>
#include <string.h>
int letter_count (char* s)
{
int i = 0;
int len = strlen (s);
int letter = 0;
while (i < len)
{
if (s[i] != '\0' && s[i] != '.' && s[i] != ',' && s[i] != '!'
&& s[i] != '?')
{
letter++;
}
i++;
}
return letter;
}
int main ()
{
char my_word[] = "Sample word";
printf ("'%s' have %d letters",my_word, letter_count (my_word));
return 0;
}
Output:
'Sample word' have 11 letters
My teacher requested a C function with this characteristics:
int removeVowels(char *s)
{
...
}
Input (Example) : "Estaa e umaa string coom duuuplicadoos"
Output : "Esta e uma string com duplicados"
The program should also output the numbers of letters removed.
All help would be appreciated.
Attempt:
int aux[1000];
int i = 0;
int retiraVogaisRep (char *s){
if (*s == '\0'){
return 0;
}
else{
if ((*s == 'A' || *s == 'E' || *s == 'I' || *s == 'O' || *s == 'U' || *s == 'a' || *s == 'e' || *s == 'i' || *s == 'o' || *s == 'u') && aux[i] != *s){
i++;
aux[i] = *s;
return retiraVogaisRep(s + 1);
}
else if ((*s == 'A' || *s == 'E' || *s == 'I' || *s == 'O' || *s == 'U' || *s == 'a' || *s == 'e' || *s == 'i' || *s == 'o' || *s == 'u') && aux[i] == *s){
i++;
aux[i] = *s;
*s = '';
return 1 + retiraVogaisRep(s + 1);
}
else{
return retiraVogaisRep(s + 1);
}
}
}
Attemp 2 (works but is there a easier way?) :
char final[1000];
char aux[1000];
int k = 0;
int i = 0;
int y = 0;
int retiraVogaisRep (char *s){
if (*s == '\0'){
while (k < y){
*(s - i) = final[k];
i--;
k++;
}
while (i >= 0){
*(s - i) = final[1000];
i--;
}
return 0;
}
else{
if ((*s == 'A' || *s == 'E' || *s == 'I' || *s == 'O' || *s == 'U' || *s == 'a' || *s == 'e' || *s == 'i' || *s == 'o' || *s == 'u') && aux[i] != *s){
i++;
aux[i] = *s;
final[y] = *s;
y++;
return retiraVogaisRep(s + 1);
}
else if ((*s == 'A' || *s == 'E' || *s == 'I' || *s == 'O' || *s == 'U' || *s == 'a' || *s == 'e' || *s == 'i' || *s == 'o' || *s == 'u') && aux[i] == *s){
i++;
aux[i] = *s;
return 1 + retiraVogaisRep(s + 1);
}
else{
final[y] = *s;
y++;
i++;
return retiraVogaisRep(s + 1);
}
}
}
This is a possible solution:
int removeVowels(char *s)
{
char *src = s;
char *dst = s;
while (*dst != '\0')
{
switch (* ++ src)
{
case 'A': case 'a':
case 'E': case 'e':
case 'I': case 'i':
case 'O': case 'o':
case 'U': case 'u':
if (* src != * dst)
* ++ dst = * src;
break;
default:
* ++ dst = * src;
break;
}
}
return src - dst;
}
First, the first character of the input string is the first character of output -- even if it's a vowel, it certainly is not a duplicate yet!
Then we enter a loop. The loop will work until the resulting string is terminated -- so while the character pointed at by the dst pointer is not zero, do iterate.
In every iteration we advance the src pointer and fetch a character pointed at. If it is a vowel we test if it's same as the most recently accepted output character (pointed at by dst); if so, we skip it, otherwise we append it to the result (by advancing the dst pointer and copying the character.
OTOH if the character is not a vowel, we copy it with no more conditions.
Once src pointer reaches the end of the string, the zero byte (a string terminator) is copied, and the loop exits.
At this moment, src points at the end of the source string and dst points at the end of the resulting string (which starts at the same point where the source string was starting, but it can be shorter now than the source).
So the difference of pointers src - dst is exactly the number of characters (vowels) skipped.
Try it here: https://onlinegdb.com/ryNzvTUVu
int isVowel(char ch)
{
if (ch >= 'A' && ch <= 'Z')
ch = (ch - 'A') + 'a';
return (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u');
}
int removeVowels(char *s)
{
int removed = 0;
if (s)
{
while (*s != '\0')
{
char ch = *s++;
if (isVowel(ch) && (*s == ch))
{
char *src = s, *dst = s;
do {
++src;
++removed;
}
while (*src == ch);
while (*src != '\0') {
*dst++ = *src++;
}
*dst = '\0';
}
}
}
return removed;
}
Demo
The other answers (two at the time of posting this) both give excellent (and efficient) solutions. Here, I offer another – less efficient but, hopefully, simpler and clearer.
First, let's define a function to test if a character is a vowel. Whenever you end up doing something more than once in a program, or if (even though you only do it once) you get long, 'ugly' lines or blocks of code, then you should consider moving that code into a function. You never know when you might need it again and, if you do, then it's already a done deed.
int isVowel(char c)
{
static char* vowels = "AEIOUaeiou"; // Making this "static" cause initialization only once
// static char* vowels = "AEIOUWYaeiouwy"; // Alternative for Welsh people!
for (char* cp = vowels; *cp; ++cp) {
if (c == *cp) return 1; // Matched a vowel, we can return without further loops
}
return 0; // Loop finished without matching, so it's not a vowel
}
Next, the function to remove duplicate vowels. This version just runs a simple loop through the given string, copying the 'source' to the 'destination' if the removal condition isn't met. We can safely do this by overwriting the string itself, as we will never need to 'go back' and look at characters in that original string more than once.
Note, also, that we will be overwriting characters with themselves, until we have found at least one character to skip – but this is a case of sacrificing a modicum of efficiency to maintain code simplicity. There are other places where adding some complexity to the code would also make it more efficient … I'll leave these as the proverbial "exercise for the reader!"
int removeVowels(char* string)
{
int skipped = 0; // Keep a running tally of how many we removed
char *src = string, *dst = string; // Use 2 pointers (source and destination): both start at beginning of string
char previous = '?'; // Keep track of last letter - start with an 'impossible' value
while (*src) // Loop until we find the nul terminator
{
if (!isVowel(*src) || *src != previous) { // Not a vowel or not same as last ...
*dst++ = *src; // ... so copy it to 'new' string and increment destination pointer
}
else { // Otherwise, all we do is incrememnt our removals count.
++skipped;
}
previous = *src++; // Change our saved last letter, then increment the source pointer
}
*dst = '\0'; // Finally, add the nul-terminator to our modified string
return skipped;
}
Finally, a short main program to test the above code with the example input provided:
#include <stdio.h>
int main()
{
char test[] = "Estaa e umaa string coom duuuplicadoos";
int lost = removeVowels(test);
printf("Result: %s (removed %d vowels)\n", test, lost);
return 0;
}
Why is does the tolower(*(text+i)); in my if statement not get executed when I run the program?
#include <stdio.h>
#include <ctype.h>
void vowel_caser(char text[])
{
int i = 0;
while(*(text+i) != '\0')
{
if (*(text+i) == 'A' || *(text+i) == 'E' || *(text+i) == 'I' || *(text+i) == 'O' || *(text+i) == 'U')
{
tolower(*(text+i));
}
i++;
}
}
int main()
{
char test[] = "This is An example";
vowel_caser(test);
puts(test);
return 0;
}
tolower returns the new value.
It does not modify the value in-place.
If you wish to modify the character, you need:
text[i] = tolower(text[i]);
Here is my function to remove the vowels in a string;
char *removeVowels(char *inString) {
int count = 0; //to count the non vowel characters
for (int i = 0; inString[i]; i++)
if (inString[i] != 'a' || inString[i] != 'e' || inString[i] != 'u' || inString[i] != 'o' || inString[i] != 'i')
inString[count++] = inString[i]; //if character is not a vowel placed at count++
inString[count] = '\0';
return inString;
}
The problem is that it is returning the original string inputted. Any ideas?
There is a confusion between the || and && operators. You want to test that the character is different from 'a' AND different from 'e' etc.
Here is a modified version:
char *removeVowels(char *inString) {
int count = 0; // index for preserved characters
for (int i = 0; inString[i]; i++) {
if (inString[i] != 'a' && inString[i] != 'e' && inString[i] != 'i'
&& inString[i] != 'o' && inString[i] != 'u') {
inString[count++] = inString[i]; // copy the non-vowel character
}
}
inString[count] = '\0'; // set the null terminator.
return inString;
}
Note however that uppercase vowels are not removed by this function, and whether y should be considered a vowel remains to be decided.
As stated in another comment, you need to use && instead of || to make sure that the character does not match any vowels. It might be easier to create a new string and add non-vowels to that string as you go. Something like:
char *removeVowels(char *inString, int size){
char newString[size];
int count = 0;
for(int i = 0; i < size; i++){
if(inString[i] != 'a' && inString[i] != 'e' && inString[i] != 'i' && inString[i] != 'o' && inString[i] != 'u'){
newString[count] = inString[i];
count++;
}
}
newString[count] = '\0';
return newString;
}
I'm having difficulties with a program I've been instructed to write. The program should search a word for the first vowel that appears, it then should print out the index of that vowel. If there are no vowel's, it should return -1.
This is my code so far:
int firstVowel(char* string){
//Variable for case with no vowels
int notInString = -1;
int length = strlen(string);
int i;
for(i = 0; i <= length; i+=1){
if(*string == 'a' || *string == 'e' || *string == 'i' ||
*string == 'o' || *string == 'u'){
return i;
}
else if(*string != 'a' || *string != 'e' || *string != 'i' || *string != 'o' ||
*string != 'u') {
return notInString;
}
}
}
When I run it with the input "abced" it returns 0 correctly. However, when I run it as fsed it returns -1 incorrectly.
You loop does not increment string and always returns after doing the first comparison, you want
int firstVowel(char* string) {
//Variable for case with no vowels
int notInString = -1;
int length = strlen(string);
int i;
for (i = 0; i <= length; i += 1) {
if (*string == 'a' || *string == 'e' || *string == 'i' ||
*string == 'o' || *string == 'u') {
return i;
} else {
string++;
}
}
return notInString;
}
This will search the entire array, returning the index of the first vowel it sees. It cannot return notInString until it has processed the entire string.