How can I count the number of "_"
in a string like "bla_bla_blabla_bla"
?

- 37,241
- 25
- 195
- 267

- 3,124
- 3
- 17
- 15
15 Answers
#include <algorithm>
std::string s = "a_b_c";
std::string::difference_type n = std::count(s.begin(), s.end(), '_');

- 11,899
- 1
- 31
- 24

- 76,634
- 23
- 210
- 236
-
2This is the best answer. – Konchog Feb 11 '20 at 14:48
-
2Small note, but the return type is typically signed. For some reason [`std::count`](https://en.cppreference.com/w/cpp/algorithm/count) returns type `iterator_traits
::difference_type`, which for most standard containers is [`std::ptrdiff_t`](https://en.cppreference.com/w/cpp/types/ptrdiff_t), not `std::size_t`. – Daniel Stevens Apr 15 '20 at 07:48 -
As @DanielStevens pointed out, the variable holding the return value of [`std::count`](https://en.cppreference.com/w/cpp/algorithm/count) should be of type `std::string::difference_type` for maximum correctness. I submitted a request to edit the answer to write: `std::string::difference_type n = std::count(s.begin(), s.end(), '_');` – FriskySaga Oct 16 '21 at 23:03
-
5This might be a good case to use `auto`. ;) – Daniel Stevens Oct 18 '21 at 06:22
-
@EmersonXu, yup -- the answer as given doesn't even compile. ``` /usr/include/c++/9/bits/predefined_ops.h:241:17: error: ISO C++ forbids comparison between pointer and integer [-fpermissive] 241 | { return *__it == _M_value; } | ~~~~~~^~~~~~~~~~~ ``` – Raleigh L. Nov 24 '21 at 22:03
Pseudocode:
count = 0
For each character c in string s
Check if c equals '_'
If yes, increase count
EDIT: C++ example code:
int count_underscores(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++)
if (s[i] == '_') count++;
return count;
}
Note that this is code to use together with std::string
, if you're using char*
, replace s.size()
with strlen(s)
- but assign that to a variable outside the for
loop to avoid scanning the whole string on every loop iteration.
Also note: I can understand you want something "as small as possible", but I'd suggest you to use this solution instead. As you see you can use a function to encapsulate the code for you so you won't have to write out the for
loop everytime, but can just use count_underscores("my_string_")
in the rest of your code. Using advanced C++ algorithms is certainly possible here, but I think it's overkill.

- 49,103
- 10
- 104
- 136
-
39Surely we can come up with a totally unreadable templated version with lamba functions and a bind2nd() call ? – Martin Beckett Oct 05 '10 at 21:33
-
@Martin I was actually thinking of that. Unfortunately my grasp of C++ functional programming is practically non-existent. – jdmichal Oct 05 '10 at 21:34
-
14I think calling a web service would be much more fun than lambdas, then the core algorithm isn't just inscrutable, it's stored elsewhere. – Ben Voigt Oct 05 '10 at 21:35
-
1This is no homework question. I am new to c++ and don't have enough knowledge of c++ to program this in a advanced manner. Read: as small as possible. I am able to program this in a simple manner with a for loop and so on, but I was looking for an sophisticated solution, something like the solution of Diego. Next time I will give more information for the reason of the question. – andre de boer Oct 06 '10 at 07:41
-
Also, you'd want to consume contiguous occurrences in case you did not want duplicates. Like for instance, counting how many pieces you'd get after splitting a string by the desired character. – TheRealChx101 Jun 23 '16 at 01:26
-
> if you're using char*, replace s.size() with strlen(s). If you do just that with no other code modifications, you'll end up calling `strlen` and scanning the entire string on every loop iteration, making the implementation quadratic. The string length would need to be cached to avoid that. – Sergey Shevchenko Aug 10 '23 at 01:00
Old-fashioned solution with appropriately named variables. This gives the code some spirit.
#include <cstdio>
int _(char*__){int ___=0;while(*__)___='_'==*__++?___+1:___;return ___;}int main(){char*__="_la_blba_bla__bla___";printf("The string \"%s\" contains %d _ characters\n",__,_(__));}
Edit: about 8 years later, looking at this answer I'm ashamed I did this (even though I justified it to myself as a snarky poke at a low-effort question). This is toxic and not OK. I'm not removing the post; I'm adding this apology to help shifting the atmosphere on StackOverflow. So OP: I apologize and I hope you got your homework right despite my trolling and that answers like mine did not discourage you from participating on the site.

- 23,169
- 18
- 105
- 180
-
-
While that might work in practice, `true` does not equal 1, but an arbitrary value which is not 0. – Tamás Szelei Oct 05 '10 at 22:01
-
5Seriously? A purposefully obfuscated answer is the best you can do and you think it would ever be appropriate here? – Oct 05 '10 at 22:02
-
5
-
1
-
8a truly old fashioned solution would declare a prototype for sprintf instead of #including a *whole header file*! – John Dibling Oct 05 '10 at 22:05
-
7@Tamas: Of course not, but I don't have my fun while "answering" beginners' questions. – Oct 05 '10 at 22:08
-
13
-
You could replace some _ with $ signs (not sure if it is legal but it works with gcc) – Martin York Oct 05 '10 at 22:17
-
-
-
@hkBattousai in C++, you can leave the return statement out from main, and it will return zero. For other functions, it will also compile, but will be undefined behavior. – Tamás Szelei Aug 17 '13 at 17:51
-
It seems that I found an error: `printf` has to be changed into `std::printf` when using `
` – Wolf Apr 02 '14 at 10:28 -
I was not aware, that's a fair point. This is specified in the paragraph 17.6.1.2.4 of the C++11 standard (I only have the [latest draft](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf), not the finished version). In practice though, are there any compilers that implement this? – Tamás Szelei Apr 02 '14 at 10:43
-
This has undefined behavior, double underscore identifiers are [reserved in any scope](https://stackoverflow.com/a/228797), I realize this was intended as a joke or something but I'd recommend editing this into something more constructive. – jrh Aug 12 '20 at 12:40
-
1Frankly, this is the kind of snarky sh*t that keeps me from really participating here and drove me towards Reddit instead, nice effort with the apology, this is a drop in an ocean of toxicity but always nice to see... – Tab Nov 17 '22 at 22:59
-
1@Tab You can experience such behavior everywhere. The only thing you can do is growing a thick skin, expressing your distaste and quickly moving along. No need to focus on the bad apples if the basket is full of healthy ones. – ashrasmun Feb 24 '23 at 14:17
Using the lambda function to check the character is "_" then the only count will be incremented else not a valid character
std::string s = "a_b_c";
size_t count = std::count_if( s.begin(), s.end(), []( char c ){return c =='_';});
std::cout << "The count of numbers: " << count << std::endl;
-
5Please add an explanation - try not to post just plain blocks of code alone. – CertainPerformance Aug 07 '18 at 04:32
-
1What do you think, that your answer offers, what a previous answer hasn't already covered? Please edit and expand your answer. – hellow Aug 07 '18 at 06:40
-
1Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation would greatly improve its long-term value](//meta.stackexchange.com/q/114762/206345) by showing _why_ this is a good solution to the problem, and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you've made. – Tim Diekmann Aug 07 '18 at 08:52
-
Used the lambda function to check the character is "_" then only count will be incremented else not a valid character. – Nagappa Sep 05 '18 at 09:56
-
1`[]( char c ){if(c =='_') return true; }` invokes undefined behavior because you didn't return a value in all code paths – phuclv Jun 30 '20 at 09:33
-
3as @phuclv suggested, there must be also return false statement `size_t count = std::count_if( s.begin(), s.end(), []( char c ){if(c =='_') return true; else return false; });` – Zbyšek Zapadlík Jan 26 '21 at 12:39
-
3You don't need the if statement `size_t count = std::count_if( s.begin(), s.end(), []( char c ){ return c == '_'; });` – JoJo Brandon Coffman May 17 '21 at 17:04
#include <boost/range/algorithm/count.hpp>
std::string str = "a_b_c";
int cnt = boost::count(str, '_');

- 151
- 1
- 2
Count character occurrences in a string is easy:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s="Sakib Hossain";
int cou=count(s.begin(),s.end(),'a');
cout<<cou;
}

- 146,994
- 96
- 417
- 335

- 237
- 1
- 3
- 8
-
5-1 This is the same as the existing top answer from six years earlier – what was this meant to add? There is one difference: this answer uses the wrong header file. stdc++.h is specific to GCC, and even with that compiler it's only intended for use in precompiled headers. – Arthur Tacca Jun 24 '18 at 19:25
-
9**Recommended reading:** [Why should I not #include
?](https://stackoverflow.com/q/31816095/560648) – Lightness Races in Orbit Oct 24 '18 at 10:22
You name it... Lambda version... :)
using namespace boost::lambda;
std::string s = "a_b_c";
std::cout << std::count_if (s.begin(), s.end(), _1 == '_') << std::endl;
You need several includes... I leave you that as an exercise...

- 28,636
- 4
- 59
- 87
-
10
-
2@Josh: It appears to be a spinoff of the childish laughter in some [comments](http://stackoverflow.com/questions/3867890/count-character-occurrences-in-a-string/3867921#3867921). – Oct 05 '10 at 22:00
-
6Some of the world's top programmers have spent the last 15years evolving C++ to the point where we can write this - it's not childish! – Martin Beckett Oct 05 '10 at 23:08
-
Making a point that those who do not know Perl are forced to reinvent it (badly) - now that would be childish! – Martin Beckett Oct 05 '10 at 23:09
-
Oh, come on, this can also be fun! :) @Roger: Yes, it was kind of an answer to a fun comment by Martin Beckett above. @Martin: Well, yes, it is not particularly appealing, but in the expression you can see clearly _1 is refering to the first parameter to the "lambda", and that it is being compared using "==" to the character... C++0x lambda are not much better in shape, but at least they are standard :) – Diego Sevilla Oct 05 '10 at 23:40
-
@Diego: I like your answer (and wasn't calling it childish, but the comments), though I think you have much too little explanation for it to be a good answer to this question. I was just trying to show the context to Josh. – Oct 06 '10 at 00:00
-
@Diego, I guessed that (in a Perl kind of way) but in c shouldn't the first parameter be _0 ? – Martin Beckett Oct 06 '10 at 01:00
-
11
-
2why all the complexity when `std::count` already does all what is needed ? – 463035818_is_not_an_ai Jun 22 '19 at 07:50
There are several methods of std::string for searching, but find is probably what you're looking for. If you mean a C-style string, then the equivalent is strchr. However, in either case, you can also use a for loop and check each character—the loop is essentially what these two wrap up.
Once you know how to find the next character given a starting position, you continually advance your search (i.e. use a loop), counting as you go.
I would have done it this way :
#include <iostream>
#include <string>
using namespace std;
int main()
{
int count = 0;
string s("Hello_world");
for (int i = 0; i < s.size(); i++)
{
if (s.at(i) == '_')
count++;
}
cout << endl << count;
cin.ignore();
return 0;
}

- 182
- 3
- 17
You can find out occurrence of '_' in source string by using string functions. find() function takes 2 arguments , first - string whose occurrences we want to find out and second argument takes starting position.While loop is use to find out occurrence till the end of source string.
example:
string str2 = "_";
string strData = "bla_bla_blabla_bla_";
size_t pos = 0,pos2;
while ((pos = strData.find(str2, pos)) < strData.length())
{
printf("\n%d", pos);
pos += str2.length();
}

- 115
- 1
- 3
The range based for loop comes in handy
int countUnderScores(string str)
{
int count = 0;
for (char c: str)
if (c == '_') count++;
return count;
}
int main()
{
string str = "bla_bla_blabla_bla";
int count = countUnderScores(str);
cout << count << endl;
}

- 133
- 1
- 9
I would have done something like that :)
const char* str = "bla_bla_blabla_bla";
char* p = str;
unsigned int count = 0;
while (*p != '\0')
if (*p++ == '_')
count++;

- 241
- 2
- 8
Much simpler in C++23 (May be some C++20 compilers also support)
//Inputs : Your string,Search criteria
int num_items = std::ranges::count("bla_bla_blabla_bla",'_');
//Print output
std::cout << num_items << std::endl; //3

- 11,671
- 5
- 26
- 34
Try
#include <iostream>
#include <string>
using namespace std;
int WordOccurrenceCount( std::string const & str, std::string const & word )
{
int count(0);
std::string::size_type word_pos( 0 );
while ( word_pos!=std::string::npos )
{
word_pos = str.find(word, word_pos );
if ( word_pos != std::string::npos )
{
++count;
// start next search after this word
word_pos += word.length();
}
}
return count;
}
int main()
{
string sting1="theeee peeeearl is in theeee riveeeer";
string word1="e";
cout<<word1<<" occurs "<<WordOccurrenceCount(sting1,word1)<<" times in ["<<sting1 <<"] \n\n";
return 0;
}

- 8,490
- 3
- 24
- 28
public static void main(String[] args) {
char[] array = "aabsbdcbdgratsbdbcfdgs".toCharArray();
char[][] countArr = new char[array.length][2];
int lastIndex = 0;
for (char c : array) {
int foundIndex = -1;
for (int i = 0; i < lastIndex; i++) {
if (countArr[i][0] == c) {
foundIndex = i;
break;
}
}
if (foundIndex >= 0) {
int a = countArr[foundIndex][1];
countArr[foundIndex][1] = (char) ++a;
} else {
countArr[lastIndex][0] = c;
countArr[lastIndex][1] = '1';
lastIndex++;
}
}
for (int i = 0; i < lastIndex; i++) {
System.out.println(countArr[i][0] + " " + countArr[i][1]);
}
}

- 1
-
4
-
1This answer is not written in C++, because of that it doesn't answer the question. – jrh Aug 12 '20 at 14:11
-