0
bool remove_vowels(const std::string& file_name) {

    std::fstream fs{ file_name , std::ios_base::in | std::ios_base::out };   
    if (!fs) { std::cout << "Error file not open"; return false; }

    char in{};

    while (fs >> in) {

        switch (tolower(in)) { 

        case 'a': case 'e': case 'i': case 'o': case 'u':
        {
            int64_t pos{ fs.tellg() }; 
            fs.seekp(pos - 1);         
            fs << ' ';                 
            fs.seekg(pos);
            
            break;
        }
        }
    }

    return true;
}

I try to solve one exercise from: Programming: Principles and Practice Using C++ Bjarne Stroustrup

  1. Write a program that removes all vowels from a file (“disemvowels”). For example, Once upon a time! becomes nc pn tm!. Surprisingly often, the result is still readable; try it on your friends.

The text file contain: "Once upon a time"

When i try this code inside the switch case:

int64_t pos { fs.tellg() }; // it get position one character forward
        fs.seekp(pos - 1);  // i set the write position to the the character         
        fs << ' ';          // then i replace the vowel to whitespace and increment one position

i get infinite loop that overwrite all the file with these characters "nc "

its only work for me this way:

int64_t pos{ fs.tellg() }; 
            fs.seekp(pos - 1);         
            fs << ' ';                 
            fs.seekg(pos);

Why it is necessary to set the position after fs << ' '; if its already increases it?

  • [Not Reproducible](https://wandbox.org/permlink/zlyTPQXEG1WjHMpK) Working just fine without `fs.seekg(pos)`. – brc-dd Dec 02 '20 at 12:53
  • IMHO, this is not the way to do it. When you take out a vowel the rest of the text has to be 'pulled up' to close the gap. It's much easier to read the entire file into an array, do the processing there, possibly while copying to another array, if that's easier, and then write out the result to file once done. – 500 - Internal Server Error Dec 02 '20 at 12:56
  • Also what else were you expecting other than "nc " there? It is what one will get after removing vowels from "Once". Surely that's not the complete output that the code should give (actually it's giving complete output in my case, see my comment above), but in no way one can get an infinite loop by not explicitly resetting the position. The ostream extraction operator should increment the position of get/put pointer implicitly. – brc-dd Dec 02 '20 at 13:00
  • @brc-dd, I mean an endless loop that keeps writing ``nc`` not that i have in a file with these characters left. and i think if the writing command do it i dont need to explicit do it –  Dec 02 '20 at 13:06
  • 1
    In C I/O it is necessary to use a file positioning function in between switching from reading to writing or from writing to reading. I guess your example proves that the same requirement exists for C++ I/O. – john Dec 02 '20 at 13:07
  • @john, thenk you. I tried to find something on the internet that explains it, But maybe this is the situation –  Dec 02 '20 at 13:16
  • You can open the file A for read, and another file B for write. Read A and write to B if it is not a vowel, otherwise skip the writing. After closed file, remove A file, and name B as A. – ytlu Dec 02 '20 at 13:16
  • ytlu , 500 - Internal Server Error. Thanks for yours suggestions –  Dec 02 '20 at 13:19
  • @zin There is no statement in the code you posted here which prints to stdout/stderr. Maybe the problem is with your driver function? Because I don't think anything like that should occur in general. Please post the complete code. Hopefully, after that we will be able to explain you more. – brc-dd Dec 02 '20 at 13:24
  • @ytlu Yes that will be my recommendation also, much cleaner and less confusing – WARhead Dec 02 '20 at 13:24
  • @zin std::ofstream bFilre("outfile,txt"); std::ifstream aFile("disemvowels.txt"); afile >> a; if (a!='a' || .....) bFile < – ytlu Dec 02 '20 at 13:25
  • @brc-dd. Thanks for the time, I do not write anything to std::cout/cerr, just for the exercise I created a text file that contains the sentence "once upon a time", and I pass to the main function the name of the file and then I go into the file to see with it replaced the letters –  Dec 02 '20 at 13:33
  • @zin Two of my recommended implementations: [1](https://wandbox.org/permlink/GaZ0uOs3UCTfkk3b), [2](https://wandbox.org/permlink/Lk5Ay3BiVZ3PRMa0). Give them a look :) [Change implementation of `isVowel` to whatever suits you best.] – brc-dd Dec 02 '20 at 13:56
  • @brc-dd Thenk you. –  Dec 02 '20 at 14:32

0 Answers0