using str::find and find_first_of and last_of - c++

Im not sure if I used find_first of and last_of correctly, but what I want to do is that I need to print error when it finds _ on the beginning or at the end of my code, plus when it finds two or more _ next to each other, like this lol___, lol__lol, _lol_, _lol, lol_, and one more rule, _ cannot be in front of capital letter, like this lol_Lol
here is my code
std::string::size_type n;
std::string::size_type n2;
std::string::size_type n3;
std::string const ss = slovo;
n = ss.find('_');
n2 = ss.find_first_of('_');
n3 = ss.find_last_of('_');
if (n2 == std::string::npos && n3 == std::string::npos) {
cout << "chyba" << endl;
}else if(n == std::string::npos){
string s = transform(slovo);
cout << s << endl;
}else{
string s = untransform(slovo);
cout << s << endl;
}
EDIT>
if ( !ss.empty() && ss.front() == '_' && ss.back() == '_' )
{
cout << "Chyba" << endl;
} else {
if ( ss.length() > 3 && ss.find( '__', 1, ss.length() - 2 ) != std::string::npos )
{
if (n == std::string::npos){
string s = transform(slovo);
cout << s << endl;
}else{
string s = untransform(slovo);
cout << s << endl;
}
}else{
cout << "chyba" << endl;
}
}
EDIT2:
cin >> slovo;
}
std::string::size_type n;
std::string const ss = slovo;
n = ss.find('_');
// kontrola podtrznika
if ( ss.empty() && ss[0] == '_' && ss[ss.length() - 1] == '_' )
{
cout << "chyba" << endl;
}
if ( ss.length() > 3 && ss.find( "__", 1, ss.length() - 2 ) != std::string::npos )
{
cout << "chyba" << endl;
}
if (n == std::string::npos)
{
string s = transform(slovo);
cout << s << endl;
}else{
string s = untransform(slovo);
cout << s << endl;
}

if those functions return npos it means the character couldn't be found in the string. So if one of them returns that, all 3 of them will.
So this code outputs 'chyba' it there's no _ in the string or calls untransform otherwise. From your description, that's not what you intend.
You really need to scan through the string for all those conditions. And if you want to check the first and last characters of the string, use ss[0] and ss[ss.length() - 1] (taking appropriate care you don't have a string of length 0 or 1).

It is obvious that the two function calls will give you the same result
n = ss.find('_');
n2 = ss.find_first_of('_');
In this context they are equivalent.
If I have understood you correctly you need to determine whether the first and the last characters in a string are underscores and whether the string contains two adjacent undescores within itself.
To determine the first case it is simple to write
if ( !ss.empty() && ss.front() == '_' && ss.back() == '_' )
{
//...
}
To find at least two adjacent underscores excluding the first and the last characters you can write
if ( ss.length() > 3 && ss.find( "__", 1, ss.length() - 2 ) != std::string::npos )
{
//...
}

Related

How do you find the number of occurences of a certain word in a sentence when reading in the sentence character by character?

For example, if I wanted to find the number of times that the word "MY" appears in a user-inputted sentence, how would I do that? Is it even possible to do this if I'm reading in the sentence one character at a time with a while-loop?
Sample input would be something like: "My house is here"
My current output is:
Number of words.........4
Number of uppercase letters.........1
Number of lowercase letters........12
Number of vowels.........6
Number of substring MY.........0
where number of substring MY should be 1.
Here's what I currently have:
#include <iostream>
#include <string>
#include <cstring>
#include <iomanip>
using namespace std;
bool isvowel(char c) {
if (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' || c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
return true;
} else {
return false;
}
}
int main() {
char c;
int words = 0;
int upperCount = 0;
int lowerCount = 0;
int vowels = 0;
int my = 0;
cout << "Enter a sentence: ";
while (cin.get(c), c != '\n') {
if (isupper(c)) {
upperCount++;
}
if (islower(c)) {
lowerCount++;
}
if (isspace(c)) {
words++;
}
if (isvowel(c) == true) {
vowels++;
}
if (c == 'M' || c == 'm') {
if (c+1 == 'Y' || c+1 == 'y') {
my++;
}
}
}
cout << left << "Number of words" << setfill('.') << setw(10) << right << words + 1 << endl;
cout << left << "Number of uppercase letters" << setfill('.') << setw(10) << right << upperCount << endl;
cout << left << "Number of lowercase letters" << setfill('.') << setw(10) << right << lowerCount << endl;
cout << left << "Number of vowels" << setfill('.') << setw(10) << right << vowels << endl;
cout << left << "Number of substring MY" << setfill('.') << setw(10) << right << my << endl;
system("Pause");
return 0;
}
This can be done in many ways, you almost have one. I will not give you the exact solution but you can try something like this: (written in Java)
// String sentence = "My house is here";
// word = "My"
private int getWordCount(String sentence, String word) {
char[] charArr = sentence.toCharArray();
String currWord = "";
int count = 0;
for(char c : charArr) {
if(c != ' ') { currWord += c; } // if c is not space it gets appended to the current word
else {
if(currWord.toLowerCase().equals(word.toLowerCase())) {
count++;
}
currWord = "";
}
}
return count;
}
Keep a track of the current string. If the current character is not a whitespace, append it to the string; else, the string becomes empty.
For each string, you could compare it to the target string. This comparison will have O(n) complexity, where n is the length of the string.
To optimise it further, you could build a trie for the target string. Since you're already processing one character at a time, the string matching could be done in O(1) instead of O(n).

How to prevent C++ buffer overflow if the user enters two or more strings separated by white spaces?

I'm a student, and I am currently working on C++ Classes. I am making a program which is supposed to ask a user to input a float point number not greater that 99.99 as a price of fuel at a gas station. I have created code that saves the user input in to a char array, and created limits so that the user can't input more than 2 dots, for example (2..2). The maximum number of characters is 5 including one dot. Now, everything works fine except for if the user enters two sets of strings before hitting enter. I have a problem because the second string messes up with other cin statements in the loop.
The code will also take the finalized char array input, and than covert it to a float variable so that the further calculations can be computed easily.
I am working on a Windows system, and Visual Studio 2017 C++.
I have tried detecting the single white space in an if/else statement, but it seems that white space is not detected as a single char array member, like this ex. else if (str[count] == ' ') , and than asking to re enter the correct input without the white space. getline() function could not work on a char array, so I couldn't discard the characters entered after including and after the white space in this way. I have tried changing the char array to a string, but still if the user inputs two or more strings separated by white space, my program keeps reading it in to cin over again.
int main()
{
int count = 0;
int lenFlag = 0, mainFlag = 0;
float result = 0;
int len;
char str[6] = "00000";
//string str ="00000";
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);
//This part will ask the user to set the price of fuel
//for the gas pump program. The programming project segment
//is from a book by Walter Savitch "Absolute C++".
while (mainFlag == 0)
{
cout << "Please enter the fuel price in dollars $";
cin >> str;
len = strlen(str);
cout << "strlen is = " << len << endl;
while (len <= 5 && mainFlag == 0)
{
count = 0, lenFlag = 0;
while (count < len && lenFlag == 0)
{
if (count == 0 && (str[count] < 48 || str[count] > 57))
{
cout << "The first input member must be a number."
"You must use a number between 0-9.\n"
"Try again: ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 0 && (str[count] < 48 || str[count] > 57)
&& str[count] != '.')
{
cout << "You must enter number between 0-9, or a decimal delimiter.\n"
"Try again, : ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 0 && (str[0] == '.' && str[1] == '.') || (str[0] == '.' && str[2] == '.') ||
(str[0] == '.' && str[3] == '.') || (str[0] == '.' && str[4] == '.') ||
(str[1] == '.' && str[2] == '.') || (str[1] == '.' && str[3] == '.') ||
(str[1] == '.' && str[4] == '.') || (str[2] == '.' && str[3] == '.') ||
(str[2] == '.' && str[4] == '.') || (str[3] == '.' && str[4] == '.'))
{
cout << "You have entered more than 1 decimal delimiter, try again: ";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count > 1 && str[0] > 48 && str[0] < 58 && str[1]>47
&& str[1] < 58 && str[2]>47 && str[2] < 58)
{
cout << "Maximum number is 99.99, try again:\n";
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (str[count] == ' ')
{
cout << "Typing whitspace is not an option!!" << endl;
cout << "Try again!!" << endl;
cin >> str;
len = strlen(str);
lenFlag = 1;
}
else if (count == len - 1 && lenFlag == 0)
{
//cout << "Main flag switches to 1!!" << endl;
mainFlag = 1;
}
count++;
}
} //while(lenCopy <= 5) loop end
if (len > 5)
{
cout << "Either non-numbers were entered, or a negative
number, or an incorrect " << endl;
cout << "number size. Enter a maximum size of 5
including a .dot for decimal number" << endl;
cout << "Maximum number is 99.99." << endl;
mainFlag = 0;
}
}//mainflag loop ends
int dotpos = 0;
for (int n = 0; n < len; n++)
{
if (str[n] == '.')
{
//dotpos = n + 1;
dotpos = len - n - 1;
cout << "dotpos = " << dotpos << endl;
}
else
{
result = result * 10 + (str[n] - '0');
//Line above is a float and character mix as a math equation.
cout << "result " << n << " = " << result << endl;
}
}
if (dotpos > 0)
result = result / (power(10, dotpos));
cout << "You have set the cost at $" << result << " per gallon." << endl;
system("pause");
return 0;
}
Occasional stack around str variable has been corrupted, and that happens when I heavily try to mess with the user input just to check if the program can crash. That's why I need to know how to clear the input after the white space. I solved the stack corruption problem by changing the char array to string, but still not the excess characters that potential users might throw down at the program.
If you must use character arrays, I highly recommend restricting the amount of characters read from the console.
The std::istream::getline() is well suited for this:
const unsigned int LIMIT = 10;
char number_as_text[LIMIT];
std::cout << "Enter a floating point number, less than 10 characters: ";
std::cin.getline(number_as_text, LIMIT);
You can then use a function like strtod to convert the string to floating point variable.
I have found one good way to solve a problem of the string buffer overflow. It uses
cin>>ws; followed by getline() function. The two need to be used in conjunction, and
than the read will be only the first string of characters and everything after the whitespace will be trashed.
cout << "Do you want to set cost in gallons or liters? "
"\nPress G for gallons or L for liters: ";
cin >> ws;
getline(cin, chooseSetCost);
while (chooseSetCost != "G" && chooseSetCost != "g" && chooseSetCost != "L" && chooseSetCost != "l")
{
cout << "Incorrect input. Try again: ";
cin >> ws;
getline(cin, chooseSetCost);
cout << "choose cost is = " << chooseSetCost << endl;
}

Unexpectedly recieving "std::out_of_range" error while using the same function

I've written a recursive palindrome function that in first code receives only a word, and in second code receives a sentence. Yet unexpectedly second code is giving me "out of range" error.
this function (which is working correctly) is used in both codes:
bool palindrome( string str, int first, int last )
{
if( first == str.size() - 1 ) //if string is a single alphabet.
return true;
if( str[ first ] == str[ last ] )
return palindrome( str.substr( first + 1, last - 1 ), first, last - 2 );
}
in first code it works as intended even if I input a very long string:
int main()
{
string str = "madamhelloollehmadam";
palindrome( str, 0, str.size() - 1 ) ? cout << "palindrome!" << '\n' : cout << "not palindrome." << '\n';
}
In second code, I need to convert the input sentence to a word, also making all characters to lowercase (i do all these in other functions). I literally inputed same string in second code yet still i get error at bottom of page:
int main()
{
string str = "madam hello olleh madam"; //this becomes "madamhelloollehmadam" after going to "normalString" function.
palindrome( normalString(str), 0, normalString(str).size() - 1 ) ? cout << "palindrome!" << '\n' : cout << "not palindrome." << '\n';
}
This is the error I get (I won't get this error for first code that gets a word and not a sentence yet both "palindrome" functions are the same. I'm guessing something is wrong with "normalString" function yet I couldn't detect any size differences ...)
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr
Aborted
also this is normalString function:
string normalString( string str )
{
vector<string> vec;
for( int i = 0; i < str.size(); ++i )
vec.push_back( charToString(str[ i ]) );
for( int i = 0; i < vec.size(); ++i )
{
if( !isAlpha( vec[ i ] ) )
vec[ i ].erase();
if( isupper( stringToChar(vec[ i ]) ) )
vec[ i ] = charToString( tolower( stringToChar( vec[ i ] ) ) );
}
string str2 = vectorToString( vec );
return str2;
}
This is all of my second code:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <locale>
using namespace std;
bool palindrome( string, int, int );
bool isAlpha( string );
string charToString( char );
string normalString( string );
char stringToChar( string );
string vectorToString( vector<string> );
int main()
{
cout << "Enter a word or a sentence: ";
string str;
while( cin >> str )
{
palindrome( normalString(str), 0, normalString(str).size() - 1 ) ? cout << str << " is palindrome!" << " (" << normalString(str) << ") "
<< '\n' : cout << str << " is not palindrome!" << " (" << normalString(str) << ") " << '\n';
cout << "Enter a word or a sentence: ";
}
return 0;
}
string vectorToString( vector<string> vec )
{
stringstream ss;
for( int i = 0; i < vec.size(); ++i )
ss << vec[ i ];
string str;
ss >> str;
return str;
}
string charToString( char c )
{
stringstream ss;
string s;
ss << c;
ss >> s;
return s;
}
char stringToChar( string str )
{
stringstream ss;
ss << str;
char c;
ss >> c;
return c;
}
bool isAlpha( string s )
{
return s == "a" || s == "b" || s == "c" || s == "d" || s == "e" || s == "f" || s == "g" || s == "h" || s == "i" || s == "j" || s == "k" || s == "l"||
s == "m" || s == "n" || s == "o" || s == "p" || s == "q" || s == "r" || s == "s" || s == "t" || s == "u" || s == "v" || s == "w" || s == "x"||
s == "y" || s == "z" ||
s == "A" || s == "B" || s == "C" || s == "D" || s == "E" || s == "F" || s == "G" || s == "H" || s == "I" || s == "J" || s == "K" || s == "L"||
s == "M" || s == "N" || s == "O" || s == "P" || s == "Q" || s == "R" || s == "S" || s == "T" || s == "U" || s == "V" || s == "W" || s == "X"||
s == "Y" || s == "Z" ;
}
string normalString( string str )
{
vector<string> vec;
for( int i = 0; i < str.size(); ++i )
vec.push_back( charToString(str[ i ]) );
for( int i = 0; i < vec.size(); ++i )
{
if( !isAlpha( vec[ i ] ) )
vec[ i ].erase();
if( isupper( stringToChar(vec[ i ]) ) )
vec[ i ] = charToString( tolower( stringToChar( vec[ i ] ) ) );
}
string str2 = vectorToString( vec );
return str2;
}
bool palindrome( string str, int first, int last )
{
if( first == str.size() - 1 ) //if string is a single alphabet.
return true;
if( str[ first ] == str[ last ] )
return palindrome( str.substr( first + 1, last - 1 ), first, last - 2 );
}
There are many problems with this code.
The palindrome function
First, let's rewrite the signature a little bit. Since palindrome doesn't need a copy of the string, we pass in a const reference instead. The indexes should also be changed to std::size_t because that is the type used for indexing strings.
bool palindrome(const std::string &str, std::size_t first, std::size_t last) {
Next, we need to handle the case where the string only has one characters… but it is also important to handle the case where the string has zero. Here's the original code:
// if (first == str.size() - 1) // Wrong!
First of all, this doesn't do what it says. The length of the string we are processing is supposed to be from first to last, not from first to size() - 1 (otherwise why does last even exist?) Second of all, this won't work if size() is 0. It will overflow! Here is the corrected code.
// Empty string, or only one character
std::size_t length = last - first;
if (length <= 1)
return true;
Next, we compare the first and last character. But the last character isn't actually str[last], it's str[last-1].
if (str[first] == str[last - 1])
Since we have the convenient first and last parameter, let's use them instead of calling substr:
return palindrome(str, first + 1, last - 1);
But we have to remember to return if the condition fails...
return false;
}
The normalString function
It turns out that std::string has push_back, so you don't need a vector, and isAlpha can be changed to operate on char instead of string, which makes it much simpler.
bool isAlpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
std::string normalString(std::string str) {
std::string result;
for (char c : str) {
if (isAlpha(c))
result.push_back(std::tolower(c));
}
return result;
}
Full code
Also removed using namespace std;
#include <iostream>
#include <string>
#include <vector>
#include <locale>
bool palindrome(const std::string &, std::size_t, std::size_t);
std::string normalString(std::string);
int main() {
while (true) {
std::cout << "Enter a word or a sentence: ";
std::string str;
if (!(std::cin >> str))
break;
str = normalString(str);
if (palindrome(str, 0, str.size())) {
std::cout << str << " is palindrome!"
<< " (" << str << ")\n";
} else {
std::cout << str << " is not palindrome!"
<< " (" << normalString(str) << ") \n";
}
}
return 0;
}
bool isAlpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
std::string normalString(std::string str) {
std::string result;
for (char c : str) {
if (isAlpha(c))
result.push_back(std::tolower(c));
}
return result;
}
bool palindrome(const std::string &str, std::size_t first, std::size_t last) {
// Empty string, or only one character
std::size_t length = last - first;
if (length <= 1)
return true;
if (str[first] == str[last - 1])
return palindrome(str, first + 1, last - 1);
return false;
}
Using Windows Debug in Visual Studio, you can pinpoint the problem to a specific line.
So here's your problem: in function normalString(string) you must do this:
for (int i = 0; i < vec.size(); ++i)
{
if (!isAlpha(vec[i]))
vec[i].erase();
else if (isupper(stringToChar(vec[i]))) //this is where your error was. use visual studio to debug your application
vec[i] = charToString(tolower(stringToChar(vec[i])));
}
You were tying to use the function isupper on a weird character which made your program crash. If you use an else if statement, it'll work because it won't try to invoke isupper() if it's not a alpha character.
The lesson: use Visual Studio debug mode
EDIT: I believe you tried to do this isupper('{0}'). isupper() does not like string terminators apparently (it'll crash)

C++ Multiple delimiters with more than one char

In c++, I'm having trouble coding multiple delimiters with single char delimiters and string delimiters (e.g. "<=" as a delimiter as opposed to '='). The code below works with single char delimiters (I've set the delimiters as space, comma, dot, plus and equal) and separates the words in string line nicely. However, I don't know how to add string delimiters to this code.
std::string delimiters = " ,.+=";//I want "<=" added as a single delimiter
std::string line = "this+is,a.string=testing one";
std::size_t prev = 0, pos;
while ((pos = line.find_first_of(delimiters, prev)) != std::string::npos)
{
if (pos > prev)
{
cout << line.substr(prev, pos-prev) << endl;
prev = pos + 1;
}
}
if (prev < line.length()){
cout << line.substr(prev, std::string::npos) << endl;
}
Here is one way you could do it by erasing the delimiters you find from the line_copy string, having a special if statement for the special delimiter. Full example here:
auto pos = find_first_of(begin(line_copy), end(line_copy), begin(delimiters),
end(delimiters));
while (pos != line_copy.end()) {
if (pos != line_copy.end()) {
if (*pos == '<' && *(pos + 1) == '=') {
cout << "delimiter: \'";
cout << string(pos, pos + 2) << "\'" << endl;
// remove the delimiters from copy string
line_copy.erase(pos, pos + 2);
}
else {
cout << "delimiter: \'" << *pos << "\'" << endl;
// remove the delimiters from copy string
line_copy.erase(pos, pos + 1);
}
}
cout << endl;
pos = find_first_of(begin(line_copy), end(line_copy), begin(delimiters),
end(delimiters));
}
I would change the line
rev = pos + 1
in the following way:
if (pos > prev)
{
cout << line.substr(prev, pos-prev) << endl;
prev = line.find_first_not_of(delimiters, pos))
}
So once you hit a delimiter then you move to the fiurst char not being a delimiter.
Do a two character search one by one.
Search for "<" first and if found search for an immediate "=" if found, do substr otherwise continue searching.

Finding substring within string C++ (find "el" in "hello")

OK, so I was looking for an algorithm that could help me find a string within a substring.
The code I was using before was from a similar question but it doesn't do it.
// might not be exposed publicly, but could be
int index_of(string const& haystack, int haystack_pos, string const& needle) {
// would normally use string const& for all the string parameters in this
// answer, but I've mostly stuck to the prototype you already have
// shorter local name, keep parameter name the same for interface clarity
int& h = haystack_pos;
// preconditions:
assert(0 <= h && h <= haystack.length());
if (needle.empty()) return h;
if (h == haystack.length()) return -1;
if (haystack.compare(h, needle.length(), needle) == 0) {
return h;
}
return index_of(haystack, h+1, needle);
}
int index_of(string haystack, string needle) {
// sets up initial values or the "context" for the common case
return index_of(haystack, 0, needle);
}
this doesn't return the start index of "el" on the string "hello" and I can't figure it out.
EDIT:
OK, let me show you a bit more of the code including some real-life examples:
I'm trying to analyze a string that is a path to a file I want to sort in my filesystem.
An input example is this:
input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv
when I try to parse this string to get the name of the by detecting the presence of SxxExx,I look for "s0","S0", etc (I know it's not the best implementation I was just trying to see if it worked and look at the code later). So when I use that input, what I get on the output is:
input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv
aux: 0p.HDTV.x264-IMMERSE.mkv
input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv
aux: 1.720p.HDTV.x264-IMMERSE.mkv
input:/media/seagate/lol/Sons.of.Anarchy.S04.720p.HDTV.x264/Sons.of.Anarchy.S04E01.720p.HDTV.x264-IMMERSE.mkv
aux: 264-IMMERSE.mkv
intended output for aux: S04E01.720p.HDTV.x264-IMMERSE.mkv
So as you can see it's just looking for any char that is in the string and stops, which also accounts for the multiple valid "found"s which should've been just the one.
the full code where I'm trying to use this is:
bool StringWorker::isSeries(size_t &i) {
size_t found1, found2, found3, found4, found5, found6;
found1 = input->find_last_of("S0"); //tried several find functions including the
found2 = input->find_last_of("S1"); //index_of() mentioned above in the post
found3 = input->find_last_of("S2");
found4 = input->find_last_of("s0");
found5 = input->find_last_of("s1");
found6 = input->find_last_of("s2");
if (found1 != string::npos) {
if (input->size() - found1 > 6) {
string aux = input->substr(found1, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found1;
return true;
}
}
}
if (found2 != string::npos) {
if (input->size() - found2 > 6) {
string aux = input->substr(found2, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found2;
return true;
}
}
}
if (found3 != string::npos) {
if (input->size() - found3 > 6) {
string aux = input->substr(found3, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found3;
return true;
}
}
}
if (found4 != string::npos) {
if (input->size() - found4 > 6) {
string aux = input->substr(found4, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found4;
return true;
}
}
}
if (found5 != string::npos) {
if (input->size() - found5 > 6) {
string aux = input->substr(found5, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found5;
return true;
}
}
}
if (found6 != string::npos) {
if (input->size() - found6 > 6) {
string aux = input->substr(found6, input->size());
cout << "input:" << *input << endl;
cout << "aux: " << aux << endl;
if (isalpha(aux.at(0)) && isdigit(aux.at(1)) && isdigit(aux.at(2))
&& isalpha(aux.at(3)) && isdigit(aux.at(4))
&& isdigit(aux.at(5))) {
i = found6;
return true;
}
}
}
return false;
}
Can you see anything wrong here?
Why don't you use the find() method of std::string -> link.
This code returns the index through index = sub_str.find("el"):
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string sub_str="abc def ghi jk lmnop hello";
string sub_str2;
size_t index;
index = sub_str.find("el");
sub_str2 = sub_str.substr (index);
cout<<"index = "<<index<<"\n";
cout<<sub_str2<<"\n";
return 0;
}
For finding a substring and its index in a string you can try this out -
int find_sub(const std::string& mstring,sub)
{
int lensub=sub.length(),len=mstring.length(),f=0,pos;
std::string b="";
for(int i=0;i<len-lensub;i++)
{
for(int j=i,k=0;j<i+lensub;j++,k++)
b[k]=mstring[j];
if(b.compare(sub)==0)
{
f=1;
pos=i;
break;
}
}
if(f==1)
cout<<"substring found at: "<<pos+1;
else
cout<<"substring not found!";
return f;
}
You also check how many times substring appears by removing break; and increasing value of f every time. Also get their indexes by converting pos to an array.