How to find a character in a string? - c++

I have already checked topics similar to this one but no one has been able to solve this problem.
So, I have to look for a character inside a string but it doesn't seem to work.
if (tracciatonuovos.find('T'))
{
nterminale++;
}
The counter does not increase. But if I try to find an empty space, it counts for me, and yet the string is full
First value is string, second is length of string, and third is the value of counter "nterminale".

use the find function from the std::string class
std::string mystr = "Some String with T";
size_t apos = mystr.find("T");
Read more about it here
If you want to find the first occurrence use :
find_first_of
And if you want to repeatedly find all occurrences of a specific character you will also need to specify a search start position and will need to write a loop say something like :
size_t pos = 0;
while((pos = mystr.find(whatever, pos)) != std::string::npos)
{
pos +=1;
// and your other logic here
}

Related

Check string for recurrence of specific character

How can I search inside of a string for more than one occurrence of a specific character (in this case a period .)?
I have already tried adapting the answer from this question, but I think I am doing it wrong.
std::string periodCheck = i.convert_to<std::string>();
char subString = '.';
std::size_t pos = periodCheck.find(subString, 0);
int counter;
while(pos != std::string::npos){
counter++;
if(counter > 1){
std::cout << "\nError: Multiple periods\n";
return false;
}
}
The first line simply converts from a Boost multi-precision cpp_dec_float (named i) to a string. I know that this part of the code works, because I use it effectively elsewhere in the program.
I am trying to check if a string contains more than one period. If the string has more than one period in it, the function returns false.
How can I achieve this?
If you find a period, then your next logical step would also be to search again, starting with the next character position.
However, if you review your code, you will not be able to find any place where it is actually searching again. There's no call to find() inside the while loop.
A while loop is not required at all. All you need to do is to call find() a second time, specifying pos+1 as the starting position for the second search, and check the results again. If you find another period, you can call it a wrap. Nothing is to be gained by searching for any remaining periods in the string. You have your answer.
std::size_t pos = periodCheck.find(subString, 0);
if (pos != std::string::npos)
{
pos=periodCheck.find(subString, pos+1);
if (pos != std::string::npos)
return false;
}

Searching and replacing all occurrence of a string in a char array c++

I have a char array and I want to find all the positions of a specific substring and then I will replace all the substring with something different.
for example:
char [35] = "the boy stole the cup from the table.";
1. I want to print out every position where "the" is. I have found some functions like find but it only finds the first position of what I want. I tried using a loop but that did not also work out.
I also want to replace all occurence of "the" with something like "that"
can someone show me how to achieve this. And I am working specifically with the char array and not string class.
Try this function . i think it will work.
void find_and_replace(string& source, string const& find, string const& replace)
{
for(string::size_type i = 0; (i = source.find(find, i)) != string::npos;)
{
source.replace(i, find.length(), replace);
i += replace.length();
}
}
content = "this is c++ programming";
find_and_replace(content, "c++", "java");

Sub strings, grabbing a piece in the middle, with random sizes

I have a file with outputs like so,
Joel[12813/76561198008530803] was taken by Huey[3924/252820590256923]
I have set up a getline that will scan for the word taken and store it into a string, I tried using substr but I'm having an issue. The issue is that the numbers between the brackets can be different sizes so when I try something along the lines of find_first_of("/"); in combination with substr, I can't use the second parameter or it might cut off numbers. I get everything past the first forward slash.
What I want in the end is to extract just this portion 76561198008530803 of the string.
What I tried,
while (getline(read, line))
{
if (line.find("taken") != string::npos) {
size_t pos = line.find_first_of("/");
extension = line.substr(pos + 1);
output << extension << endl;
}
Thanks for taking the time!
You can use std::string::find_first_of repeatedly.
size_t pos = line.find_first_of("/");
size_t pos2 = line.find_first_of("]");
std::string extension = line.substr(pos + 1,pos2-1-pos);

Cannot get second while to loop properly

I'm making a function that removes elements from a string. However, I cant seem to get both of my loops to work together. The first while loop works flawlessly. I looked into it and I believe it might be because when "find_last_of" isn't found, it still returns a value (which is throwing off my loop). I haven't been able to figure out how I can fix it. Thank you.
#include <iostream>
#include <string>
using namespace std;
string foo(string word) {
string compare = "!##$";
string alphabet = "abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
while(word.find_first_of(compare) < word.find_first_of(alphabet)) {
int position = word.find_first_of(compare);
word = word.substr(++position);
}
while(word.find_last_of(compare) > word.find_last_of(alphabet)){
int size = word.length();
word = word.substr(0, --size);
}
return word;
}
int main() {
cout << foo("!!hi!!");
return 0;
}
I wrote it like this so compound words would not be affected. Desired result: "hi"
It's not entirely clear what you're trying to do, but how about replacing the second loop with this:
string::size_type p = word.find_last_not_of(compare);
if(p != string::npos)
word = word.substr(0, ++p);
It's not clear if you just want to trim certain characters from the front and back of word or if you want to remove every one of a certain set of characters from word no matter where they are. Based on the first sentence of your question, I'll assume you want to do the latter: remove all characters in compare from word.
A better strategy would be to more directly examine each character to see if it needs to be removed, and if so, do so, all in one pass through word. Since compare is quite short, something like this is probably good enough:
// Rewrite word by removing all characters in compare (and then erasing the
// leftover space, if any, at the end). See std::remove_if() docs.
word.erase(std::remove_if(word.begin(),
word.end(),
// Returns true if a character is to be removed.
[&](const char ch) {
return compare.find(ch) != compare.npos;
}),
word.end());
BTW, I'm not sure why there is both a compare and alphabet string in your example. It seems you would only need to define one or the other, and not both. A character is either one to keep or one to remove.

Instead of having different size_t variables, can I use just one for searching a std::string multiple times?

I am wondering if it is possible to cut down how many size_t variables I use here. Here is what I have:
std::size_t found, found2, found3, found4 /* etc */;
Each has its own string to find:
found1 = msg.find("string1");
found2 = msg.find("string2");
found3 = msg.find("string3");
found4 = msg.find("string4");
// etc
If the word is found, then it will discard and prevent the message to be shown:
if (found1 != std::string::npos)
{
SendMsg("You cannot say that word!");
}
I have else if statements until found21. I'd like to cut everything down in size, so it would be clean, but I don't have a clue how to do it. I would also like it to lowercase the word. I have never used tolower at all either, so I would appreciated it if someone would help me.
To lowercase a string, you can do
std::transform(msg.begin(), msg.end(), msg.begin(), std::tolower);
Transform takes a begin and end iterator as the first and second arguments, and for each element in that range, applies the fourth argument (a function) and assigns it to what the third iterator is pointing to and increments it. By passing msg.begin() as both the first and third arguments, it will assign the result of the function to what it passed to it. So transform will basically do this:
for (auto src = begin(msg), dst = begin(msg); src != end(msg); ++src, ++dst)
*dst = tolower(*src);
but using transform is so much nicer.
To check whether a string contains any of a list of substrings, you can use a for loop with a vector:
vector<string> bad_strings { "bad word 1", "bad word 2", "etc" };
for (auto i = begin(bad_strings); i != end(bad_strings); ++i)
if (msg.find(*i)) {
SendMsg("You cannot say that word!");
break; // stop when you find it matches even one bad string
}