views:

333

answers:

5

Hi all,

I am just trying to count the number of white spaces to the LEFT of a line from a text file. I have been using

count( line.begin(), line.end(), ' ' );

but obviously that includes ALL white spaces to the left, in between words and to the right. So basically what I'm wanting it to do is once it hits a non-space character stop it from counting the white spaces.

Thanks everyone.

+5  A: 

How about

line.find_first_not_of(' ');

EDIT: In case it's all spaces:

unsigned int n = line.find_first_not_of(' ');
if(n==s.npos)
    n = line.length();
Beta
if (n == -1)!!!!!!!!
Martin York
You should be using line.npos instead of -1. That constant may be different depending on the platform you are using.
Billy ONeal
@Billy ONeal: you're right, thanks; fixed.
Beta
+2  A: 
int i = 0;
while ( isspace( line[i++] ) )
    ;
int whitespaceCnt = i-1;
pajton
A: 

Is line a string?

In that case you want to std::string::find_first_not_of to find the first non-whitespace, then use std::count on the remainder of the line like this:

std::string::size_type firstNonSpace = line.find_first_not_of(' ');
std::size_t result = std::count(line.begin()+(firstNonSpace==std::string::npos?0:firstNonSpace),line.end(),' ');
Joe Gauterin
Don't you already know the amount of space when you've found the first non space? Why the call to `std::count`?
Billy ONeal
+6  A: 

Find the first non white space character.

std::string            test = "     plop";
std::string::size_type find = test.find_first_not_of(" \t");  // Note: std::string::npos returned when all space.

Technically not white space (as other characters are also white space).
Are you trying to count or strip white space?

If you are trying to strip white space then the stream operators do it automatically.

std::stringstream testStream(test);
std::string       word;

testStream >> word;  // white space stripped and first word loaded into 'word'
Martin York
Just trying to count, not strip. Thanks
+8  A: 

Assuming line is a std::string, how about:

#include <algorithm>
#include <cctype>
#include <functional>

std::string::const_iterator firstNonSpace = std::find_if(line.begin(), line.end(),
   std::not1(std::ptr_fun<int,int>(isspace)));
int count = std::distance(line.begin(), firstNonSpace);
Nick Meyer
+1: Technically the only correct answer as it does real white space detection.
Martin York
@Martin York: Yes. It returns the length of the string. `find_if` returns the ending iterator on failure.
Billy ONeal
Minor nitpicking: It would be more general to use a `std::string::const_iterator` here. Counting whitespaces doesn't modify the string and should be doable given a constant string. +1 anyway.
sbi
@sbi: This is why we really really need the `auto` keyword to act like it's C++0x :)
Billy ONeal
`std::not1(isspace)` doesn't compile. It should either `not1(ptr_fun<int,int>(isspace))` for `<cctype>` variant or `not1(bind2nd(ptr_fun(isspace<char>), locale("")))` for `<locale>`'s one.
J.F. Sebastian
@J.F. Sebastian - A nice big upvote for your comment as that got this answer working correctly. And Thank you @Nick Meyer, your solution fits the needs of my program!
@J.F. Sebastian, thanks, I was sort of writing that off the top of my head. Editing my answer.
Nick Meyer
@Billy: Absent of the new `auto` semantics, what we can do is to put this into a function template with the iterators being a template parameter. This or being pedantic. I'm pedantic. I`d even write `const std::string::const_iterator firstNonSpace = ...` and `const std::size_t count = ...`, just to be sure. (But then, I'd probably also put it into it's own function template nevertheless...)
sbi
@sbi: Yes yes I agree. Just saying it's a hell of a lot less verbose with `auto` :)
Billy ONeal