For every instance of a character/substring in string - c++

I have a string in C++ that looks like this:
string word = "substring"
I want to read through the word string using a for loop, and each time an s is found, print out "S found!". The end result should be:
S found!
S found!

Maybe you could utilize toupper:
#include <iostream>
#include <string>
void FindCharInString(const std::string &str, const char &search_ch) {
const char search_ch_upper = toupper(search_ch, std::locale());
for (const char &ch : str) {
if (toupper(ch, std::locale()) == search_ch_upper) {
std::cout << search_ch_upper << " found!\n";
}
}
}
int main() {
std::string word = "substring";
std::cout << word << '\n';
FindCharInString(word, 's');
return 0;
}
Output:
substring
S found!
S found!

Related

Why is my string extraction function using back referencing in regex not working as intended?

Extraction Function
string extractStr(string str, string regExpStr) {
regex regexp(regExpStr);
smatch m;
regex_search(str, m, regexp);
string result = "";
for (string x : m)
result = result + x;
return result;
}
The Main Code
#include <iostream>
#include <regex>
using namespace std;
string extractStr(string, string);
int main(void) {
string test = "(1+1)*(n+n)";
cout << extractStr(test, "n\\+n") << endl;
cout << extractStr(test, "(\\d)\\+\\1") << endl;
cout << extractStr(test, "([a-zA-Z])[+-/*]\\1") << endl;
cout << extractStr(test, "([a-zA-Z])[+-/*]([a-zA-Z])") << endl;
return 0;
}
The Output
String = (1+1)*(n+n)
n\+n = n+n
(\d)\+\1 = 1+11
([a-zA-Z])[+-/*]\1 = n+nn
([a-zA-Z])[+-/*]([a-zA-Z]) = n+nnn
If anyone could kindly point the error I've done or point me to a similar question in SO that I've missed while searching, it would be greatly appreciated.
Regexes in C++ don't work quite like "normal" regexes. Specialy when you are looking for multiple groups later. I also have some C++ tips in here (constness and references).
#include <cassert>
#include <iostream>
#include <sstream>
#include <regex>
#include <string>
// using namespace std; don't do this!
// https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
// pass strings by const reference
// 1. const, you promise not to change them in this function
// 2. by reference, you avoid making copies
std::string extractStr(const std::string& str, const std::string& regExpStr)
{
std::regex regexp(regExpStr);
std::smatch m;
std::ostringstream os; // streams are more efficient for building up strings
auto begin = str.cbegin();
bool comma = false;
// C++ matches regexes in parts so work you need to loop
while (std::regex_search(begin, str.end(), m, regexp))
{
if (comma) os << ", ";
os << m[0];
comma = true;
begin = m.suffix().first;
}
return os.str();
}
// small helper function to produce nicer output for your tests.
void test(const std::string& input, const std::string& regex, const std::string& expected)
{
auto output = extractStr(input, regex);
if (output == expected)
{
std::cout << "test succeeded : output = " << output << "\n";
}
else
{
std::cout << "test failed : output = " << output << ", expected : " << expected << "\n";
}
}
int main(void)
{
std::string input = "(1+1)*(n+n)";
test(input, "n\\+n", "n+n");
test(input, "(\\d)\\+\\1", "1+1");
test(input, "([a-zA-Z])[+-/*]\\1", "n+n");
return 0;
}

How would I search an element in a vector string?

I'm trying to search a vector string for certain words.
For example,
vector<string> sentences = ["This is a test string","Welcome to C++!"];
string searchString = "This";
I tried
if (std::find(sentences.begin(), sentences.end(), searchString) != sentences.end()) {
cout << "Found!";
}
else {
cout << "Not Found!";
}
Now this does work but only if the searchString matches the element word for word.
For example if we set
string searchString = "This is a test string";
This will return found.
How do I search the elements individually?
Thanks!
for(std::string& s : sentences)
{
if(s.find(searchString) != std::string::npos)
{
//substring found
}
else
{
//substring not found
}
}
this should work for looking for a word in each string in the vector
There is std::find_if that lets you pass a predicate to be used instead of directly comparing elements for equality with a searchString:
auto matcher = [searchString](const std::string& element) {
return element.find(searchString) != std::string::npos;
};
if (std::find_if(sentences.begin(), sentences.end(), matcher) != sentences.end()){
cout << "Found!";
} else {
cout<< "Not Found!";
}
You can iterate over all the strings in your vector and check each string one by one if it contains the string you want to find. If the string contains the search term, you can return the whole element:
#include <iostream>
#include <vector>
#include <string>
std::string findSubstr(const std::vector<std::string>& list, const std::string& search) {
for (const std::string& str : list) {
if (str.find(search) != std::string::npos) {
return str;
}
}
return "Not found";
}
int main(int argc, const char** argv) {
if (argc < 2) {
std::clog << "Usage: " << argv[0] << " <search term>\n";
return 1;
}
std::vector<std::string> test{"This is a test string", "Welcome to C++!"};
std::cout << findSubstr(test, argv[1]) << std::endl;
}

Alternative for a loop in C++

I want to reverse a string without the use of a loop. My code with the loop looks like:
#include <iostream>
#include <string>
using namespace std;
string reverseString(string str) {
string changedString;
int strLength = int(str.length() - 1);
for(int i {strLength}; i >= 0; i--) {
changedString.push_back(str.at(i));
}
return changedString;
}
int main() {
string str;
cout << "Enter a string to reverse it:\n" << flush;
cin >> str;
cout << reverseString(str) << flush;
}
Now I need to write a function without the loop. Only the methods of String should be used. Can you help me solving this problem?
It is very simple to write such a function
std::string reverse( const std::string &s )
{
return { s.rbegin(), s.rend() };
}
Here is a demonstrative program
#include <iostream>
#include <string>
std::string reverse( const std::string &s )
{
return { s.rbegin(), s.rend() };
}
int main()
{
std::string s( "Hello World" );
std::cout << s << '\n';
std::cout << reverse( s ) << '\n';
return 0;
}
Its output is
Hello World
dlroW olleH
Well, you can do that using recursion. Here are some links if you aren't aware what recursion is : link1 and link2.
Technically it won't be a loop.
string reverseString(string str, int index, string ans) {
if (index == -1) return ans;
ans += str[index];
return reverseString(str, index - 1, ans);
}
Parameters for this function will be str as it was by default, index = size(str) - 1 and ans ans = "";
reverseString(str, size(str) - 1, "") for example.
If you want your function to take exactly one argument, then you can write wrapper function and the one I wrote will have different name - reverseStringWrapper for example and in reverseString there will be only one line - return reverseStringWrapper(str, size(str) - 1, "");
string reverseStringWrapper(string str, int index, string ans) {
if (index == -1) return ans;
ans += str[index];
return reverseString(str, index - 1, ans);
}
string reverseString(string str) {
return reverseStringWrapper(str, size(str) - 1, "");
}
How was this?
In c, You can use strrev() function to reverse the string(char*)
In c++, you can either use std::reverse() or StringBuilder.reverse()
method to reverse a string.
.
This way you can reverse the char array(char*).
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
// Function to reverse a given character array using std::reverse
void reverse(char *str)
{
std::reverse(str, str + strlen(str));
}
// main function
int main()
{
/* using C string */
char s[] = "Hello World";
reverse(s);
cout << "Reverse of the given string is : " << s;
return 0;
}
This way you can reverse the string.
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
// Function to reverse a given character array using std::reverse
void reverse(char* str)
{
std::reverse(str, str + strlen(str));
}
// main function
int main()
{
/* using C string */
// char s[] = "Techie Delight";
string s = "hello world";
int n = s.length();
// declaring character array
char char_array[n + 1];
// copying the contents of the
// string to char array
strcpy(char_array, s.c_str());
reverse(char_array);
s = char_array;
cout << "Reverse of the given string is : " << s;
return 0;
}
Hope this might Helps:)

C++ Decrease value every time string passes

I'm struggling to find a way to decrease the value in a string every time the string is shown.
Using the code below, consider that the 1st line of the text file is some text #N. #N should be replaced by a number decreasing from 18 to 1. When it reaches 0 it should go back to 18.
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
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();
}
}
int main(int argc, char * argv[])
{
std::ifstream fileIn("Answers.txt", std::ios::in | std::ios::binary);
string question;
string line;
if (!fileIn) {
cout << "Cannot open input file!" << endl;
return 1;
}
while (getline(fileIn, line)) {
if (line == "The answer can be found in a secret place in the woods.") {
fileIn.clear();
fileIn.seekg(0, ios::beg);
}
cout << "Ask a question followed by the Enter key. Or type 'exit' to Exit program.\n";
getline(cin, question);
system("CLS");
find_and_replace(line, "#N", "18");
if (question == "") {
cout << "Your input cannot be blank. Please try again.\n\n";
}
else if (question == "exit")
exit(0);
else {
cout << "Q: " + question
<< "\nA: " + line + "\n\n";
}
}
}
This code only changes #N to 18, nothing more.
Please help guys.
You have hardcoded the value to 18, and you don't have any code which decrements the number.
Try these changes
put this at the start of main
int tempVar=18;
char buffer[100];
and replace
find_and_replace(line, "#N", "18");
with
sprintf(buffer,"%d",tempVar--)
if(tempVar<0)
tempVar=18;
find_and_replace(line, "#N", buffer);
https://www.programiz.com/cpp-programming/library-function/cstdio/sprintf
You can use something like:
#include <sstream>
#include <string>
class Replacer
{
const std::string token_;
const int start_;
int current_;
public:
explicit Replacer(const std::string & token, int start)
: token_(token), start_(start), current_(start)
{
}
std::string replace(const std::string & str)
{
const std::size_t pos = str.find(token_);
if (pos == std::string::npos)
return str;
std::string ret(str);
std::ostringstream oss;
oss << current_;
ret.replace(pos, token_.size(), oss.str());
--current_;
if (current_ == 0)
current_ = start_;
return ret;
}
};
And then you can use it like:
std::string examples[] = {
"",
"nothing",
"some number #N",
"nothing",
"some other #N number",
"nothing",
"#N another test",
"nothing",
};
Replacer replacer("#N", 18);
for (int i = 0; i < 8; ++i)
std::cout << replacer.replace(examples[i]) << '\n';

string parsing for C++

I have a text file that has #'s in it...It looks something like this.
#Stuff
1
2
3
#MoreStuff
a
b
c
I am trying to use std::string::find() function to get the positions of the # and then go from there, but I'm not sure how to actually code this.
This is my attempt:
int pos1=0;
while(i<string.size()){
int next=string.find('#', pos1);
i++;}
Here's one i made a while ago... (in C)
int char_pos(char c, char *str) {
char *pch=strchr(str,c);
return (pch-str)+1;
}
Port it to C++ and there you go! ;)
If : Not Found Then returns Negative.
Else : Return 'Positive', Char's 1st found position (1st match)
It's hard to tell from your question what you mean by "position", but it looks like you are trying to do something like this:
#include <fstream>
#include <iostream>
int main()
{
std::ifstream incoming{"string-parsing-for-c.txt"};
std::string const hash{"#"};
std::string line;
for (auto line_number = 0U; std::getline(incoming, line); ++line_number)
{
auto const column = line.find(hash);
if (std::string::npos != column)
{
std::cout << hash << " found on line " << line_number
<< " in column " << column << ".\n";
}
}
}
...or possibly this:
#include <fstream>
#include <iostream>
int main()
{
std::ifstream incoming{"string-parsing-for-c.txt"};
char const hash{'#'};
char byte{};
for (auto offset = 0U; incoming.read(&byte, 1); ++offset)
{
if (hash == byte)
{
std::cout << hash << " found at offset " << offset << ".\n";
}
}
}