Search for all occurrences of a character in a string

I have comma delimited strings. I need to infer values ​​from. The problem is that these lines will never be fixed. So I decided to iterate over the groups of commas and read what is in between. To do this, I created a function that returns each position in the sample string.

Is this a smart way to do this? Is this considered bad code?

#include <string> #include <iostream> #include <vector> #include <Windows.h> using namespace std; vector<int> findLocation(string sample, char findIt); int main() { string test = "19,,112456.0,a,34656"; char findIt = ','; vector<int> results = findLocation(test,findIt); return 0; } vector<int> findLocation(string sample, char findIt) { vector<int> characterLocations; for(int i =0; i < sample.size(); i++) if(sample[i] == findIt) characterLocations.push_back(sample[i]); return characterLocations; } 
+4
source share
5 answers
 vector<int> findLocation(string sample, char findIt) { vector<int> characterLocations; for(int i =0; i < sample.size(); i++) if(sample[i] == findIt) characterLocations.push_back(sample[i]); return characterLocations; } 

As currently written, this will simply return a vector containing the int representations of the characters themselves, and not their positions, which you really want if I read your question correctly.

Replace this line:

 characterLocations.push_back(sample[i]); 

with this line:

 characterLocations.push_back(i); 

And that should give you the vector you want.

+10
source

If I were considering this, I would see it and assume that what you are really trying to do is tokenize the string, and there are already good ways to do this.

The best way I've seen is boost::tokenizer . It allows you to specify how the string is divided, and then gives you a good iterator interface for repeating each value.

 using namespace boost; string sample = "Hello,My,Name,Is,Doug"; escaped_list_seperator<char> sep("" /*escape char*/, ","/*seperator*/, "" /*quotes*/) tokenizer<escaped_list_seperator<char> > myTokens(sample, sep) //iterate through the contents for (tokenizer<escaped_list_seperator<char>>::iterator iter = myTokens.begin(); iter != myTokens.end(); ++iter) { std::cout << *iter << std::endl; } 

Output:

 Hello My Name Is Doug 

Edit If you don't need a boost dependency, you can also use getline with istringstream , as in this answer . To copy this answer a bit:

 std::string str = "Hello,My,Name,Is,Doug"; std::istringstream stream(str); std::string tok1; while (stream) { std::getline(stream, tok1, ','); std::cout << tok1 << std::endl; } 

Output:

  Hello My Name Is Doug 

It may not be what you ask, but I think it depends on your general problem that you are trying to solve.

+6
source

It looks good to me, one comment is related to the names of your variables and types. You call a vector that you are going to return characterLocations , which is of type int , when you really drop the character itself (which is a type of char ), and not its location. I'm not sure why there are more applications, but I think it would be more appropriate to pass the addresses. Or add another cookie cutter line.

0
source

Well, if your goal is to find entry indices, the following code will be more efficient, since in C ++, which gives objects as parameters, objects are copied, which is unsafe and also less efficient. A particularly true vector is the worst possible practice in this case, so the question of giving it a reference to an argument would be much better.

 #include <string> #include <iostream> #include <vector> #include <Windows.h> using namespace std; vector<int> findLocation(string sample, char findIt); int main() { string test = "19,,112456.0,a,34656"; char findIt = ','; vector<int> results; findLocation(test,findIt, results); return 0; } void findLocation(const string& sample, const char findIt, vector<int>& resultList) { const int sz = sample.size(); for(int i =0; i < sz; i++) { if(sample[i] == findIt) { resultList.push_back(i); } } } 
0
source

How reasonable this also depends on what you do with these substrings separated by commas. In some cases, it may be better (for example, faster, with less memory requirements) to avoid searching and splitting, and also just parse and process the string at the same time, possibly using a state machine.

0
source

All Articles