Aksel Mathias
Aksel Mathias

Reputation: 25

How to erase every occurences of vowels in a string

In a schools assignment we are asked to remove every occurences of vowels from a string.

So: "The boy kicked the ball" would result in "Th by kckd th bll"

Whenever a vowel is found, all the subsequent characters somehow have to shift left, or at least that's my approach. Being that I just started learning C, it may very well be that it's a ridiculous approach.

What I'm trying to do is: When I hit the first vowel, I "shift" the next char ([i+1]) to the current pos (i). the shifting then has to continue for every subsequent character, so int startshift is set to 1 so the first if block excecutes on every subsequent iteration.

The first if block also test to see if the next char is a vowel. Without such a test any character preceding a vowel would "transform" to the adjacent vowel, and every vowel except the first would still be present. However this resulted in every vowel being replaced by the preceding char, hence the if else block.

Anyway, this ugly code is what I've come up with so far. (The names used for the char* pointers make no sense (I just don't know what to call them), and having two sets of them is probably redudant.

char line[70];

char *blank;
char *hlp;

char *blanktwo;
char *hlptwo;


strcpy(line, temp->data);

int i = 0;
int j;

while (line[i] != '\n') {

  if (startshift && !isvowel(line[i+1])) { // need a test for [i + 1] is vowel

blank = &line[i+1]; // blank is set to til point to the value of line[i+1]
hlp = &line[i]; // hlp is set to point to the value of line[i]

*hlp = *blank; // shifting left

  } else if (startshift && isvowel(line[i+1])) {

blanktwo = &line[i+1]; 
hlptwo = &line[i];

*hlptwo = *blanktwo;

//*hlptwo = line[i + 2]; // LAST MOD, doesn't work


  }

  for (j = 0; j < 10; j++) { // TODO: j < NVOWELS

if (line[i] == vowels[j]) { // TODO: COULD TRY COPY EVERYTHING EXCEPT VOWELS
  blanktwo = &line[i+1]; 
  hlptwo = &line[i];

  *hlptwo = *blanktwo;

  startshift = 1;

}

  }

  i++;

}

printf("%s", line);

The code doesn't work.

with text.txt:

The boy kicked the ball
He kicked it hard

./oblig1 remove test.txt produces: Th boy kicked the ball

e kicked it hard

NB. I've omitted the outer while loop used for iterating the lines in the text file.

Upvotes: 0

Views: 734

Answers (2)

Philip Wardlaw
Philip Wardlaw

Reputation: 199

Try use std containers and objects

#include <iostream>
#include <string>
#include <vector>

std::string editStr = "qweertadoi";
std::vector<char> vowels{'i', 'o', 'u', 'e', 'a'};

int main() {

    for(unsigned int i = 0; i<editStr.size(); i++){
        for(char c: vowels){
            if(editStr.at(i) == c){
                editStr.erase(i--,1);
                break;
            }
        }
    }

    std::cout << editStr << std::endl; 
    return 0;
}

Upvotes: -1

Frerich Raabe
Frerich Raabe

Reputation: 94409

Just some food for thought, since this is homework and I don't want to spoil the fun:

You might also tackle this problem without using a second 'temp->data' buffer. If the given input string is in a modifiable memory chunk, like

char data[] = "The boy kicked the ball";

You could also write a program which maintains two pointers into the buffer:

  • One pointer points to the position in the string where the next vowel would need to be written; this pointer is advanced whenever a vowel was written.
  • The second pointer points to the position in the string where the next character to consider is read from; this pointer is advanced whenever a character is read.

If you think about it, you can see that the first pointer will not advance as fast as the second pointer (since every character is read, but not every character is written out - vowels are skipped).

If you go for this route, consider that you may need to terminate the string properly.

Upvotes: 4

Related Questions