I'm trying to use a for
loop and an if
statement to compare if any values in the string match with any in the vector. It only outputs "we have a match"
if the first character in teststring
is in the vector. Basically, it seems like the searching stops if the first character value in teststring
isn't in the SpecialChars
vector. Sorry if that is confusing, I can't think of a better way to explain it.
#include <iostream>
#include <vector>
void test()
{
std::vector<char> SpecialChars = {'!', '@', '#', '$', '%', '^', '&', '8', '(', ')', '-', ' ', '='};
std::string teststring = "loll!@";
bool test = false;
for (int i = 0; i < SpecialChars.size(); i )
{
if (teststring[i] == SpecialChars[i])
{
std::cout << "We have a match \n";
}
}
}
CodePudding user response:
teststring
has a different length than SpcialChars
, and teststring
is shorter, so your for
loop will go out of bounds of teststring
when i
reaches 6
, causing undefined behavior.
You need 2 loops, one to iterate teststring
, and one to iterate SpecialChars
, eg:
#include <iostream>
#include <vector>
#include <string>
void test()
{
std::vector<char> SpecialChars = {'!', '@', '#', '$', '%', '^', '&', '8', '(', ')', '-', ' ', '='};
std::string teststring = "loll!@";
bool found = false;
for (size_t i = 0; i < teststring.size(); i)
{
for (size_t j = 0; j < SpecialChars.size(); j)
{
if (teststring[i] == SpecialChars[j])
{
found = true;
break;
}
}
if (found) break;
}
if (found)
std::cout << "We have a match\n";
}
You can simplify the outer loop by using a range-for
loop, and eliminate the inner loop by using the standard std::find()
algorithm, eg:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
void test()
{
std::vector<char> SpecialChars = {'!', '@', '#', '$', '%', '^', '&', '8', '(', ')', '-', ' ', '='};
std::string teststring = "loll!@";
bool found = false;
for (char ch : teststring)
{
if (std::find(SpecialChars.begin(), SpecialChars.end(), ch) != SpecialChars.end())
{
found = true;
break;
}
}
if (found)
std::cout << "We have a match\n";
}
Alternatively, you could change SpecialChars
into a std::string
and use std::string::find()
on it, eg:
#include <iostream>
#include <string>
void test()
{
std::string SpecialChars = "!@#$%^&8()- =";
std::string teststring = "loll!@";
bool found = false;
for (char ch : teststring)
{
if (SpecialChars.find(ch) != std::string::npos)
{
found = true;
break;
}
}
if (found)
std::cout << "We have a match\n";
}
Alternatively, you can use a lookup table, like @paddy suggested, eg:
#include <iostream>
#include <string>
#include <climits>
void test()
{
std::string SpecialChars = "!@#$%^&8()- =";
std::string teststring = "loll!@";
bool found = false;
bool isSpecial[1 << CHAR_BIT] = {};
for(unsigned char ch : SpecialChars)
isSpecial[ch] = true;
for (unsigned char ch : teststring)
{
if (isSpecial[ch])
{
found = true;
break;
}
}
if (found)
std::cout << "We have a match\n";
}