Почему find не находит пробелы в строке?

211
14 апреля 2017, 23:22

Пытаюсь сосчитать количество пробелов в строке, но через find выводит количество всех символов, а не пробелов. Почему и какая есть альтернатива?

for(int d=0;d<=s1.length();d++){
   if(s1.find(' ')){
    spaces++;
   }
}
Answer 1

Для начала у вас задан неверный диапазон цикла

for(int d=0;d<=s1.length();d++){
             ^^^ 

Правильно было бы написать

for ( std::string::size_type d = 0; d < s1.length(); d++ ){
                                     ^^^ 

То, что делает ваш цикл, это подсчитывает количество символов в строке (если только строка не содержит пробел в самом начале), так как в этом случае условие

if(s1.find(' ')){

всегда будет истинно.

Вы могли бы записать цикл следующим образом

for ( std::string::size_type i = 0; i < s1.length(); i++ )
{
    if ( s1[i] == ' ' /* || s1[i] == '\t' */ ) ++spaces;
}

Или если вы непременно хотите использовать функцию-член класса find, то

for ( std::string::size_type pos = 0; 
      ( pos = s1.find( ' ', pos ) ) != std::string::npos;
      ++pos )
{
    spaces++;
}

Либо вы можете использовать стандартный алгоритм std::count

spaces = std::count( s1.begin(), s1.end(), ' ' );

Либо вы можете также подсчитывать и другие пробельные символы, как, например, символ табуляции, используя стандартный алгоритм std::count_if и стандартную C функцию isspace.

spaces = std::count_if( s1.begin(), s1.end(), ::isspace );

Для этого вам, естественно, помимо прочих заголовков нужно включить заголовки

#include <algorithm>
#include <cstring> 

Более корректно будет написать

spaces = std::count_if( s1.begin(), s1.end(), 
                        []( char c ) { return ::isspace( ( unsigned char )c ); } );

так как тип char может вести себя как signed char, и в этом случае если среди символов строки могут встречаться символы с отрицательными значениями кодов, то следует делать приведение к типу unsigned char при вызове isspace.

Answer 2

Используйте возможности стандартной библиотеки. В данном случае, вам нужен std::count:

    #include <iostream>
    #include <algorithm>
    #include <string>
    int main() {
        std::string str = "a b c";
        std::cout<<std::count(str.begin(), str.end(), ' ')<<'\n';
    }

http://ideone.com/ZR8B6l

Answer 3
for(int d=0;d<=s1.length();d++){  // Число итераций, на один больше числа символов
   if(s1.find(' ')){              // Вообще-то, проверяется сравнение с string::npos
    spaces++;                     // Увеличить значение
   }
}

По сути у вас код такой:
Увеличить spaces на число символов в строке плюс один, если пробел не на первом месте...

То, что вы хотите (поиск в цикле с помощью find), делается так:

int main(int argc, const char * argv[])
{
    string s = "jbcsdbl sdjkbhjskdfb sdfjkbjskdlfb sdfjkh  sdjkhjk";
    int spaces = 0;
    for(size_t pos = s.find(' '); pos != string::npos; pos = s.find(' ',pos+1))
        spaces++;
    cout << spaces << endl;
}
READ ALSO
Rest Api Ajax Get запрос

Rest Api Ajax Get запрос

Не могу отправить правильный запрос на сервер, чтобы получить с него ответь в виде json строки

256
Google apps script. Как разделить информацию в ячейке на две с помощью split() в функции OnEdit?

Google apps script. Как разделить информацию в ячейке на две с помощью split() в функции OnEdit?

Добрый деньу меня в таблице есть 2 колонки: одна для имени, вторая для фамилии

240
Проблема чтении JSON на сервере node.js

Проблема чтении JSON на сервере node.js

Сервер не распознает JSON, приходящий от клиентаИз этого поля <input type="text" id="message"> я отправляю данные посредством XMLHttpRequest:

188