Hello fellow programmers, I have a question about recursion that I do not understand, being new to C++ and all. So for this exercise I am completing, I need to: 1. Ask user for a string 2. Ask user for a string to search in the first string entered. 3. report and index of the string if it finds it. For instance the user enters the string "Search me", string to search for is "me", and the index would return "7". I am throwing my hands up at this point for some help on how to complete it, any help would be appreciated. Here is my code thus far. The stuff that is in the for loop isn't a complete thought, just FYI.
int index_of(string stringToSearchIn, string stringToSearchFor, int index)
{
if (stringToSearchIn.length() < stringToSearchFor.length())
{
cout << "Your string cannot be found." << endl;
system("PAUSE");
return OUTLIER;
}
else
{
bool found = true;
for (int i = ZERO; i < stringToSearchFor.length; i++)
{
found = found && stringToSearchIn(i) == stringToSearchFor(i);
}
return index;
}
return index_of(stringToSearchIn.substr(INCREASE), stringToSearchFor, index++);
}
int main()
{
//Initializing values
string userString;
string userSearch;
int userIndex = 0;
//Asking for user input for string
cout << "This program will find the occurence of one string inside of another." << endl;
cout << "Enter the string to be searched: " << userString;
//Getting the string
getline(cin, userString);
//Asking for user input for search input
cout << "Now enter the string you want to search for: " << userSearch;
//Getting the string
getline(cin, userSearch);
//Displaying results
cout << "The index of the substring is = " << index_of(userString, userSearch, userIndex);
//Keeping console window open until key press
system("PAUSE");
return ZERO;
}
Catch.:)
#include <iostream>
size_t index_of( const char *s, const char *t )
{
const char *p = s;
const char *q = t;
while ( *q && *p == *q ) ++p, ++q;
if ( *q == '\0' )
{
return 0;
}
else if ( *p == '\0' )
{
return -1;
}
else
{
size_t n = 1 + index_of( s + 1, t );
return n == 0 ? -1 : n;
}
}
int main()
{
const char *s = "Search me";
const char *t = "me";
size_t n = index_of( s, t );
if ( n != -1 )
{
std::cout << "string " << t << " is found at position " << n << std::endl;
}
else
{
std::cout << "string " << t << " is not found" << std::endl;
}
return 0;
}
The output is
string me is found at position 7
For other strings I did not test the function.:)
For objects of type std::string you can call it like
size_t n = index_of( s.c_str(), t.c_str() );
Otherwise if you want to write a similar recursive function for objects of type std::string then you need either to add a static local variable that to keep the current position inside the source string or add one more parameter for index or use member function substr.
Also my advice is do not use manifest constant ZERO for zero. In my opinion it is a bad style of programming. It only confuses readers because ZERO can be anything including some user-defined class.
For example (without testing)
#include <iostream>
#include <string>
std::string::size_type index_of( const std::string &s, const std::string &t )
{
static std::string::size_type pos;
if ( s.size() < t.size() ) return std::string::npos;
if ( s.compare( pos, t.size(), t ) == 0 ) return 0;
++pos;
std::string::size_type n = index_of( s, t );
--pos;
return n == std::string::npos ? std::string::npos : n + 1;
}
int main()
{
std::string s = "Search me";
std::string t = "me";
std::string::size_type n = index_of( s, t );
if ( n != std::string::npos )
{
std::cout << "string " << t << " is found at position " << n << std::endl;
}
else
{
std::cout << "string " << t << " is not found" << std::endl;
}
return 0;
}
As for your function realization then it can look for example the following way
#include <iostream>
#include <string>
std::string::size_type index_of( const std::string &stringToSearchIn,
const std::string &stringToSearchFor,
std::string::size_type index )
{
if ( stringToSearchIn.length() < stringToSearchFor.length() + index )
{
return std::string::npos;
}
else if ( stringToSearchIn.compare( index,
stringToSearchFor.length(),
stringToSearchFor ) == 0 )
{
return index;
}
else
{
std::string::size_type n =
index_of( stringToSearchIn, stringToSearchFor, ++index );
return n == std::string::npos ? std::string::npos : n;
}
}
int main()
{
std::string s = "Search me";
std::string t = "me";
std::string::size_type n = index_of( s, t, 0 );
if ( n != std::string::npos )
{
std::cout << "string " << t << " is found at position " << n << std::endl;
}
else
{
std::cout << "string " << t << " is not found" << std::endl;
}
return 0;
}
Related
Could you figure out why it keeps looping infinitely in the console? The programmer's supposed to list out each character of a user-inserted string and next to each unique character, in brackets, it's supposed to display the number of times that character occurs in the string... no idea why.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main () {
string input;
cout << "input string: " , cin >> input;
sort (input.begin() , input.end());
while (!input.empty()) {
int j{1}, i{0};
while (input.at(i) == input.at(i+1)) {
j++;
i++;
}
cout << input.at(i) << " (" << j << "), ";
input.substr(i);
}
return 0;
}
This statement
input.substr(i);
does not change the object input itself.
So, either you will have an infinite loop if for some index i input.at(i) is not equal to input.at(i+1), or you can have an exception out of range because i + 1 can be equal to input.size().
From the description of the member function at
Throws: out_of_range if pos >= size().
The program can be implemented in different ways. For example the following way
#include <iostream>
#include <string>
#include <algorithm>
int main()
{
std::cout << "input string: ";
std::string input;
std::cin >> input;
std::sort( input.begin() , input.end() );
for ( size_t i = 0; i < input.size(); )
{
size_t j = input.find_first_not_of( input[i], i );
if ( j == std::string::npos ) j = i + 1;
if ( i != 0 ) std::cout << ", ";
std::cout << input[i] << " (" << j - i << ")";
i = j;
}
std::cout << '\n';
return 0;
}
The program output is
input string: Hello
H (1), e (1), l (2), o (1)
Or you can use the standard container std::map or std::unordered_map as for example
#include <iostream>
#include <string>
#include <map>
int main()
{
std::cout << "input string: ";
std::string input;
std::cin >> input;
std::map<char, size_t> m;
for ( const auto &c : input )
{
++m[c];
}
bool first = true;
for ( const auto &p : m )
{
if ( !first ) std::cout << ", ";
std::cout << p.first << " (" << p.second << ")";
first = false;
}
std::cout << '\n';
return 0;
}
If you want that characters of the inputted string were output in the order in which they are present in the string then the program can look like
#include <iostream>
#include <string>
#include <map>
int main()
{
std::cout << "input string: ";
std::string input;
std::cin >> input;
auto less = [&input]( const auto &c1, const auto &c2 )
{
return input.find( c1 ) < input.find( c2 );
};
std::map<char, size_t, decltype( less )> m( less );
for ( const auto &c : input )
{
++m[c];
}
bool first = true;
for ( const auto &p : m )
{
if ( !first ) std::cout << ", ";
std::cout << p.first << " (" << p.second << ")";
first = false;
}
std::cout << '\n';
return 0;
}
Or without changing the original string and without using an additional container the program can look the following way.
#include <iostream>
#include <string>
int main()
{
std::cout << "input string: ";
std::string input;
std::cin >> input;
for ( size_t i = 0; i < input.size(); i++ )
{
size_t j = 0;
while ( j != i && input[j] != input[i] ) j++;
if ( j == i )
{
size_t count = 1;
while ( ++j < input.size() )
{
if ( input[j] == input[i] ) ++count;
}
if ( i != 0 ) std::cout << ", ";
std::cout << input[i] << " (" << count << ")";
}
}
std::cout << '\n';
return 0;
}
The program output might look like
input string: elephant
e (2), l (1), p (1), h (1), a (1), n (1), t (1)
I'm working on a project which needs to find the number of words and the indices of each word in the paragraph ...I have written the code which is counting the number of word in a string but I stuck with finding the indices of words,
such as : Hi John How are you I miss you ..
I need to print the indices like : 0 1 2 3 4 5 6 7
here is the code:
int _tmain(int argc, _TCHAR* argv[])
{
int count_words(std::string);
std::string input_text;
std::cout<< "Enter a text: ";
std::getline(std::cin,input_text);
int number_of_words=1;
int counter []={0};
for(int i = 0; i < input_text.length();i++)
if(input_text[i] == ' ')
number_of_words++;
std::cout << "Number of words: " << number_of_words << std::endl;
//std:: cout << number_of_words << std::endl;
system ("PAUSE");
}
Hopefully this helps. Edited to include use of count_words function.
#include <iostream>
#include <sstream>
void count_words(std::string);
int main(){
std::string input_text, output_text;
std::cout<< "Enter a text: ";
std::getline(std::cin,input_text);
count_words(input_text);
system ("PAUSE");
return 0; //MUST RETURN AN INTEGER VALUE FROM 'INT MAIN'
}
void count_words(std::string inputString){
std::string output_text;
std::stringstream indexes;
int number_of_words=0; //If there are no words, it would be false, make it 0.
//int counter []={0}; //This serves no purpose.
if(!inputString.empty()){// test to make sure it isn't empty.
number_of_words++;
for(int i = 0; i < inputString.length();i++){ // For loops should have curly braces {} containing their statement.
if(inputString[i] == ' '){
number_of_words++;
}
if((isalpha(inputString[i]))&&inputString[i-1]==' '){ //test for following space separated word
indexes << i << " ";
}
}
}
output_text = indexes.str(); //convert stringstream to string
std::cout << "Number of words: " << number_of_words << std::endl;
//std:: cout << number_of_words << std::endl; //duplicate info
std::cout << "Indexes: " << output_text << std::endl;
}
I'm not sure if i understand the question. You only need print the "indices"?? like this? (Using your own code)
#include <iostream>
#include <vector>
#include <string>
void stringTokenizer(const std::string& str, const std::string& delimiter, std::vector<std::string>& tokens) {
size_t prev = 0, next = 0, len;
while ((next = str.find(delimiter, prev)) != std::string::npos) {
len = next - prev;
if (len > 0) {
tokens.push_back(str.substr(prev, len));
}
prev = next + delimiter.size();
}
if (prev < str.size()) {
tokens.push_back(str.substr(prev));
}
}
int main()
{
std::vector <std::string> split;
std::string input_text;
std::cout<< "Enter a text: ";
std::getline(std::cin,input_text);
stringTokenizer(input_text, " ", split);
int number_of_words = 0;
for (std::vector<std::string>::iterator it = split.begin(); it != split.end(); it++, number_of_words++) {
std::cout << *it << " " << number_of_words << std::endl;
}
}
I am looking at various examples of reading an input file and counting the occurrences of a word. Then give it a variable to count.
Lets say we have an input file and you want to look for how many times the word "account" or word "like" shows up and give it the variable "1.2". So when you find the word, count how many times it occurs and then times it by 1.2 .
How would you go about doing this?
EDIT: This is the only way I know how. However, this pre-searches the word versus letting the user search it
#include <iostream>
#include <fstream>
using namespace std;
int main(void)
{
int option=0; //option number
ifstream inputFile;
string filename;
cout << "Welcome\n" << endl;
//Getting the input file
cout << "Enter input data file name:";
cin >> filename;
cout << endl;
fin.open(filename.c_str()); // change to C-string
if (!inputFile) {// makes sure file exist
cout << "Unable to open " << filename << endl;
cin.get();
return 1;
}
do {
cout << "5- Count frequency of the following three words individually: I, like, is" << endl;
cout << "6 - To quit";
cout << endl;
cin >> option;
int iWord = 0;
int likeWord = 0;
int isWord = 0;
if (option == 5) {
string word;
do {
inputFile >> word;
if (word == "I") iWord++;
else if (word== "like") likeWord++;
else if (word == "is") isWord++;
}while (inputFile.good());
cout << "The word I is repeated " << iWord << " times" << endl;
cout << "The word is has been repeated " << isWord << " times" << endl;
cout << "The word like is repeated " << likeWord << " times" << endl << endl;
}
inputFile.clear(); // clear fail bit or seekg won't work!
inputFile.seekg (0, ios::beg);
}while (option != 6);
return 0;
}
Not the most efficient way (especially for one word), but maybe this could give you direction:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <unordered_map>
void tokenize( const std::string & line, std::unordered_map< std::string, size_t > & map_count )
{
for( std::string::size_type pos_start = 0, pos_end = 0; ( pos_end != std::string::npos ) && ( pos_start = line.find_first_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", pos_end ) ) != std::string::npos; )
{
pos_end = line.find_first_not_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", pos_start );
std::string current_word = ( pos_end == std::string::npos ) ? line.substr( pos_start ) : line.substr( pos_start, pos_end - pos_start );
std::unordered_map< std::string, size_t >::iterator iter( map_count.find( current_word ) );
if( iter == map_count.end() )
map_count.insert( std::pair< std::string, size_t >( current_word, 1 ) );
else
++( iter->second );
}
}
void countWordsInFile( const std::string & filename, std::unordered_map< std::string, size_t > & map_count )
{
std::ifstream in( filename );
std::string line;
size_t count = 0;
if( in.is_open() )
while( std::getline( in, line ).good() )
tokenize( line, map_count );
}
double countAndWeigh( const std::string & filename, const std::string & word, double weight )
{
std::unordered_map< std::string, size_t > map_count;
countWordsInFile( filename, map_count );
std::unordered_map< std::string, size_t >::const_iterator iter( map_count.find( word ) );
return ( iter != map_count.end() ) ? iter->second * weight : 0;
}
int main( int argc, char ** argv )
{
if( argc == 4 )
std::cout << countAndWeigh( argv[1], argv[2], strtod( argv[3], nullptr ) ) << std::endl;
return 0;
}
I'm having several input strings containing numbers and letters. Sometimes the space is missing. I would like to add an additional Space each time the string changes from numbers to letters or from letters to numbers.
Example inputs:
"30EinsteinStreet"
"548 Roe Drive5500 TestCity"
"44B SaarlouisDrive1234Testtown"
they should become:
"30 EinsteinStreet"
"548 Roe Drive 5500 TestCity"
"44 B SaarlouisDrive 1234 Testtown"
My existing function is not working and I think far to complex. Can anyone provide an easy solution? Preferably using modern C++11 classes but no Boost. Also I'm using GCC so all the regex stuff doesn't work for me.
Thanks
Here is my existing method:
inline string separateAlphanumChunks(const std::string& s)
{
string ret = "";
const int sl = s.length();
//int inserts = 0;
if (sl<=4)
return s;
for (int i=0 ; i< sl ; i++)
{
// cerr << "separateAlphanumChunks: '" << ret << "'" <<endl;
// check if index would go out of range
if (i+4 > sl)
{
ret += s.substr (i,sl-i);
//TODO add the remain to ret
break;
}
// seperate chars
const char c0 = s[i+0];
const char c1 = s[i+1];
// check if 0 and 1 are the same class
const bool c0c = isCharAnInt (c0);
const bool c1c = isCharAnInt (c1);
bool class0 = false;
if (c0c == c1c)
{
class0 = c0c;
}
else
{
ret += c0;
// cerr << "cont1: '" << c0 << "'" <<endl;
continue;
}
// seperate chars
const char c2 = s[i+2];
const char c3 = s[i+3];
// check if 2 and 3 are the same class
const bool c2c = isCharAnInt (c2);
const bool c3c = isCharAnInt (c3);
bool class2 = false;
if (c2c == c3c)
{
class2 = c2c;
}
else
{
ret += c0;
// cerr << "cont2: '" << c0 << "'" <<endl;
continue;
}
// check if the 2 classes are different
if (class0 != class2)
{
// split!
ret += c0+(c1+string(" ")+c2)+c3;
//inserts++;
i+=3;
}
else
{
ret += c0;
// cerr << "cont3: '" << c0 << "'" <<endl;
continue;
}
}
// remove double spaces
//replaceStringInPlace(ret, " "," ");
//cerr << "separateAlphanumChunks: '" << ret << "'" <<endl;
return ret;
}
inline bool isCharAnInt (char c)
{
//TODO might be able to use isdigit() here
int i = c - '0';
return ((i>=0) && (i<=9));
}
I saw various complex answers, and this is the reason to give another answer too.
The answer of your problem is exactly in the problem statement:
"add an additional Space each time the string changes from numbers to letters or from letters to numbers."
So here is exactly what you want ( I used some code from a previous answer ) the compilation should be done using the flag -std=c++11
#include <string>
#include <iostream>
using namespace std;
enum charTypeT{ other, alpha, digit};
charTypeT charType(char c){
if(isdigit(c))return digit;
if(isalpha(c))return alpha;
return other;
}
string separateThem(string inString){
string oString = "";charTypeT st=other;
for(auto c:inString){
if( (st==alpha && charType(c)==digit) || (st==digit && charType(c)==alpha) )
oString.push_back(' ');
oString.push_back(c);st=charType(c);
}
return oString;
}
int main(){
string str1 = "30EinsteinStreet";
string str2 = "548 Roe Drive5500 TestCity";
string str3 = "44B SaarlouisDrive1234Testtown";
cout << separateThem(str1) << endl;
cout << separateThem(str2) << endl;
cout << separateThem(str3) << endl;
}
I think what you are looking for and what Ajay is hinting at is a finite-state machine to parse strings.
Although this is not a C++11 solution, and you might find more elegant solutions by means of regex, I provided the code sample below.
#include <iostream>
#include <sstream>
bool isDigit(const char c)
{
bool res = true;
switch (c)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
break;
default:
res = false;
break;
}
return res;
}
std::string separateNumbers(const std::string& inputString)
{
const size_t N = inputString.length();
std::ostringstream os;
bool readDigit = false;
for (size_t i = 0; i < N; ++i)
{
if (isDigit(inputString[i]))
{
if ((i > 0) && (i < N) && (! readDigit))
{
if (inputString[i] != ' ')
os << ' ';
}
readDigit = true;
}
else
{
if ((i > 0) && (i < N) && (readDigit))
{
if (inputString[i] != ' ')
os << ' ';
}
readDigit = false;
}
os << inputString[i];
}
return os.str();
}
int main(int argc, char** argv)
{
std::string strings[3] = {
"30EinsteinStreet",
"548 Roe Drive5500 TestCity",
"44B SaarlouisDrive1234Testtown"
};
for (int i = 0; i < 3; ++i)
{
std::cout << "input #" << i << ": " << strings[i] << std::endl;
std::cout << "output #" << i << ": " << separateNumbers(strings[i]) << std::endl;
std::cout << std::endl;
}
return 0;
}
What I would suggest is to go trough a iteration trough string elements.
Something like that will help:
#include <string>
#include <iostream>
using namespace std;
string separateThem(string inString){
string numbers = "1234567890";
string oString = "";
int i;
for(i=0; i<inString.size()-1; i++){
if ((numbers.find(inString[i]) != string::npos) && (numbers.find(inString[i+1]) == string::npos) && !isspace(inString[i+1])){
oString += inString.substr(i,1) + " ";
}
else if ((numbers.find(inString[i]) == string::npos) && (numbers.find(inString[i+1]) != string::npos) && !isspace(inString[i+1])){
oString += inString.substr(i,1) + " ";
}
else oString += inString.substr(i,1);
}
oString += inString.substr(i,1);
return oString;
}
int main(){
string str1 = "30EinsteinStreet";
string str2 = "548 Roe Drive5500 TestCity";
string str3 = "44B SaarlouisDrive1234Testtown";
cout << separateThem(str1) << endl;
cout << separateThem(str2) << endl;
cout << separateThem(str3) << endl;
}
If you execute this the output will be:
30 EinsteinStreet
548 Roe Drive 5500 TestCity
44 B SaarlouisDrive 1234 Testtown
Hope this helps :)
Here is my five cents.
#include <iostream>
#include <string>
#include <cctype>
std::string SeparateAlphanumChunks( const std::string &s )
{
std::string::size_type n = 0;
bool ctype = std::isdigit( s[0] );
for ( char c : s )
{
if ( !ctype != !std::isdigit( c ) )
{
ctype = std::isdigit( c );
if ( !isblank( c ) ) ++n;
}
}
std::string t;
t.reserve( s.size() + n );
ctype = std::isdigit( s[0] );
for ( char c : s )
{
if ( !ctype != !std::isdigit( c ) )
{
ctype = std::isdigit( c );
if ( !isblank( c ) ) t.push_back( ' ');
}
t.push_back( c );
}
return t;
}
int main()
{
for ( const std::string &s : { "30EinsteinStreet",
"548 Roe Drive5500 TestCity",
"44B SaarlouisDrive1234Testtown"
} )
{
std::cout << SeparateAlphanumChunks( s ) << std::endl;
}
return 0;
}
The output is
30 EinsteinStreet
548 Roe Drive 5500 TestCity
44 B SaarlouisDrive 1234 Testtown
You also may change the string "in place". For example
#include <iostream>
#include <string>
#include <cctype>
std::string & SeparateAlphanumChunks( std::string &s )
{
std::string::size_type n = 0;
bool ctype = std::isdigit( s[0] );
for ( char c : s )
{
if ( !ctype != !std::isdigit( c ) )
{
ctype = std::isdigit( c );
if ( !isblank( c ) ) ++n;
}
}
s.reserve( s.size() + n );
ctype = std::isdigit( s[0] );
for ( std::string::size_type i = 0; i < s.size(); i++ )
{
if ( !ctype != !std::isdigit( s[i] ) )
{
ctype = std::isdigit( s[i] );
if ( !isblank( s[i] ) )
{
s.insert( i, 1, ' ' );
}
}
}
return s;
}
int main()
{
for ( std::string s : { "30EinsteinStreet",
"548 Roe Drive5500 TestCity",
"44B SaarlouisDrive1234Testtown"
} )
{
std::cout << SeparateAlphanumChunks( s ) << std::endl;
}
return 0;
}
Upgrade to GCC 4.9 (whose first release was back in April) and use a simple regex:
#include <regex>
#include <iostream>
std::string fix(const std::string& in)
{
return std::regex_replace(
in,
std::regex("(?:([a-zA-Z])([0-9]))|(?:([0-9])([a-zA-Z]))"),
"\\1\\3 \\2\\4",
std::regex_constants::format_sed
);
}
int main()
{
const std::string in[] = {
"30EinsteinStreet",
"548 Roe Drive5500 TestCity",
"44B SaarlouisDrive1234Testtown"
};
for (auto el : in)
std::cout << fix(el) << '\n';
}
/*
"30 EinsteinStreet"
"548 Roe Drive 5500 TestCity"
"44 B SaarlouisDrive 1234 Testtown"
*/
(live demo)
I would suggest you to iterator the string as raw-string (i.e. string::c_str()), and generate a new string altogether. This would be my algorithm (not very complete):
For each character, check if it is a digit. If no, just append to new string.
If yes, check if it is first character - if yes, just append to new string.
If the digit is last character, then append to new string.
If digit is falling in between, check if last appended character was space. If no space was there, put a space, and then put digit.
If last inserted character was a digit, and this is also a digit, insert.
However, if last was digit, but this is not a digit (and not a space), then insert a space.
You may need to tweak it further.
What if string is like this:
"enter 144 code here 123 "
?
I have read an entire file into a string from a memory mapped file Win API
CreateFile( "WarandPeace.txt", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 )
etc...
Each line is terminated with a CRLF. I need to find something on a line like "Spam" in the line "I love Spam and Eggs" (and return the entire line (without the CRLF) in a string (or a pointer to the location in the string) The original string cannot be altered.
EDITED:
Something like this:
string ParseStr( string sIn, string sDelim, int nField )
{
int match, LenStr, LenDelim, ePos, sPos(0), count(0);
string sRet;
LenDelim = sDelim.length();
LenStr = sIn.length();
if( LenStr < 1 || LenDelim < 1 ) return ""; // Empty String
if( nField < 1 ) return "";
//=========== cout << "LenDelim=" << LenDelim << ", sIn.length=" << sIn.length() << endl;
for( ePos=0; ePos < LenStr; ePos++ ) // iterate through the string
{ // cout << "sPos=" << sPos << ", LenStr=" << LenStr << ", ePos=" << ePos << ", sIn[ePos]=" << sIn[ePos] << endl;
match = 1; // default = match found
for( int k=0; k < LenDelim; k++ ) // Byte value
{
if( ePos+k > LenStr ) // end of the string
break;
else if( sIn[ePos+k] != sDelim[k] ){ // match failed
match = 0; break; }
}
//===========
if( match || (ePos == LenStr-1) ) // process line
{
if( !match ) ePos = LenStr + LenDelim; // (ePos == LenStr-1)
count++; // cout << "sPos=" << sPos << ", ePos=" << ePos << " >" << sIn.substr(sPos, ePos-sPos) << endl;
if( count == nField ){ sRet = sIn.substr(sPos, ePos-sPos); break; }
ePos = ePos+LenDelim-1; // jump over Delim
sPos = ePos+1; // Begin after Delim
} // cout << "Final ePos=" << ePos << ", count=" << count << ", LenStr=" << LenStr << endl;
}// next
return sRet;
}
If you like it, vote it up. If not, let's see what you got.
If you are trying to match a more complex pattern then you can always fall back to boost's regex lib.
See: http://www.boost.org/doc/libs/1_41_0/libs/regex/doc/html/index.html
#include <iostream>
#include <string>
#include <boost/regex.hpp>
using namespace std;
int main( )
{
std::string s;
std::string sre("Spam");
boost::regex re;
ifstream in("main.cpp");
if (!in.is_open()) return 1;
string line;
while (getline(in,line))
{
try
{
// Set up the regular expression for case-insensitivity
re.assign(sre, boost::regex_constants::icase);
}
catch (boost::regex_error& e)
{
cout << sre << " is not a valid regular expression: \""
<< e.what() << "\"" << endl;
continue;
}
if (boost::regex_match(line, re))
{
cout << re << " matches " << line << endl;
}
}
}
Do you really have to do it in C++? Perhaps you could use a language which is more appropriate for text processing, like Perl, and apply a regular expression.
Anyway, if doing it in C++, a loop over Prev_delim_position = sIn.find(sDelim, Prev_delim_position) looks like a fine way to do it.
system("grep ....");