xmllmx
xmllmx

Reputation: 42379

How to remove the leading white spaces but keep middle spaces in C++ `ifstream`?

For example, I have a file with the following contents:

     Hello John Smith
               Hello Jack Brown
                     OK I love you

Note that each sentence has some leading white spaces. I want to use std::fstream to read them line by line, and want to remove the leading white spaces but keep the spaces between the words in a sentence.

My desired output should be as follows:

Hello John Smith
Hello Jack Brown
OK I love you

I also find this post gives many trivial methods to my question. However, I think none of them is elegant in terms of modern C++. Is there any more elegant means?

Upvotes: 1

Views: 548

Answers (2)

James Kanze
James Kanze

Reputation: 153977

As a complement to Nawaz' answer: it's worth pointing out that Boost has a String_Algo library, with (along with a lot of other things) functions like trim, which will simplify the code a lot. If you're doing any text processing at all, and you can't or don't want to use Boost, you should implement something similar yourself for your toolkit (e.g. a function MyUtils::trim, based on Nawaz' algorithms).

Finally, if you may need someday to handle UTF-8 input, then you should look into ICU.

Upvotes: 4

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361612

std::ifstream file("input.txt");

std::string line;

while(std::getline(file,line))
{
     auto isspace = [](unsigned char ch) { return std::isspace(ch); };

     //find the first non-space character
     auto it = std::find_if_not(line.begin(), line.end(), isspace);

     line.erase(line.begin(), it); //erase all till the first non-space

     std::cout << line << "\n";
}

Note that we could just pass std::isspace as third argument to std::find_if_not, but there are overloads of std::isspace which causes compilation error — to fix this you can use cast though, as:

auto it = std::find_if_not(line.begin(), 
                           line.end(), 
                           static_cast<int(*)(int)>(std::isspace));

which looks ugly. But because of the function type in the cast, the compiler is able to figure out which overload you intend to use in the code.

Upvotes: 5

Related Questions