Annoying problem with string::find()

C

Chris Mantoulidis

I posted this here one day ago but it seems like it hasn't been put up
for some unknown reason. That gives me a chance to say things a bit
better in this post.

1st of all let's desribe the problem: In ParamGenerate() I want to
find all whitespaces before a certain point in one string. Thus I use
the string::find() function. However it seems like this function
ignores some whitespaces :/ This is really weird and I need your help.

Okay since the function ParamGenerate() itself isn't compilable, I
want to include the least compilable code which I wouldn't say is too
big :) But you gotta understand the purpose of my program so you can
understand better what I'm trying to do in ParamGenerate(). My program
will receive input in the following format:

[ <prefix> ] <COMMAND> <middle param> <middle param> ... <middle
param> <final param>

So the <prefix> is optional (and if inserted is a colon ':') and we
can have MANY <middle param>s (that must not include a colon ':' or a
space ' ') and just one <final param> (which starts with a ':' and can
contain spaces).

I just want to do that kind of seperation to my input with
ParamGenerate() (I remove the leading colon before calling
ParamGenerate()). However my ParamGenerate() seems to misfunction and
I think that this is caused by the find() function.

<btw> I have also tried implementing the ParamGenerate() function by
going through all the characters in the string and checking if they're
a space but I still have the same problem </btw>

<btw 2> Also in ParamGenerate() if I try to resize the vector to the
result of ParamCount() I get a segfault :/ This is the command I used:

params.resize(ParamCount(s));
</btw 2>

Here's the least compilable code:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

string arg;
vector<string> params(1024);


/*
COMMAND IS LIKE
:user@host <CMD> <PARAMS>

and params are like

<PARAMS> = <MIDDLE PARAMS> <MIDDLE PARAMS> ... <MIDDLE PARAMS> <FINAL
PARAM>

middle params are params that contain no spaces or columns ':'

.... TO BE CONTINUED ...
*/


string RemoveLeadingColon(const string &s) {
string s2 = s;
if (s2[0] == ':') s2.erase(0,1);
return s2;
}

int ParamCount(const string &s) {
int count=1;
string::size_type i;
for (i=0; i < s.length(); i++) {
if (s == ' ' /*&& !found_column*/ )
count++;
else if (s == ':' /*&& !found_column*/ ) {
return count;
}
}
return count;
}

void ParamGenerate(const string &s) {
cout << "initializing vars...\n";
string::size_type first_column = s.find(':');
if (first_column == string::npos) first_column=s.length();
string::size_type white_space=0;
string::size_type last=0;
int curr_param=0;
cout << "starting search...\n";
while ((white_space = s.find(' ', white_space+1)) != string::npos &&
white_space <= first_column) {
cout << "found space...\n";
params[curr_param] = s.substr(last,white_space);
cout << "substring is \"" << s.substr(last,white_space) << "\"\n";
last=white_space+1;
curr_param++;
}
params[curr_param] = s.substr(first_column,s.length());
}

int main() {

cout << "gimme a cmd:\n";
getline(cin,arg,'\n');
cout << "you gave me: " << arg << "\n";

cout << "without leading ':' it is: " << RemoveLeadingColon(arg) <<
"\n";
ParamGenerate(RemoveLeadingColon(arg));
cout << "Params generated\n";

int what;
do {
cout << "tell me a num: ";
cin >> what;
if (what <= ParamCount(RemoveLeadingColon(arg)) && what >= 1)
cout << "param[" << what << "] = " << params[what-1] << "\n";
else
cout << "wrong index\n";
} while (what != 0);

return 0;

}
 
S

Sharad Kala

Chris Mantoulidis said:
I posted this here one day ago but it seems like it hasn't been put up
for some unknown reason. That gives me a chance to say things a bit
better in this post.

I haven't delved a lot into your code.
I think perhaps this is an easier way to parse an input string.

#include<iostream>
#include<string>
#include<vector>
#include <sstream>
using namespace std;

template <class T>
vector<T> StringToVector( string& Str )
{
istringstream iss( Str );
return vector<T>( istream_iterator<T>(iss),istream_iterator<T>() );
}

int main(){
string str = " Here is a command ";
vector<string> vec(StringToVector<string>(str));
vector<string>::const_iterator itr;
for(itr = vec.begin(); itr!= vec.end (); ++itr)
cout << *itr; // Print Hereisacommand
}

Best wishes,
Sharad
 
J

John Harrison

Chris Mantoulidis said:
I posted this here one day ago but it seems like it hasn't been put up
for some unknown reason. That gives me a chance to say things a bit
better in this post.

cout << "found space...\n";
params[curr_param] = s.substr(last,white_space);
cout << "substring is \"" << s.substr(last,white_space) << "\"\n";

You'll have better results with

params[curr_param] = s.substr(last,white_space - last);
cout << "substring is \"" << s.substr(last,white_space - last) << "\"\n";

but I wouldn't swear that your code doesn't have other bugs in it.

john
 
C

Chris Mantoulidis

John Harrison said:
Chris Mantoulidis said:
I posted this here one day ago but it seems like it hasn't been put up
for some unknown reason. That gives me a chance to say things a bit
better in this post.

cout << "found space...\n";
params[curr_param] = s.substr(last,white_space);
cout << "substring is \"" << s.substr(last,white_space) << "\"\n";

You'll have better results with

params[curr_param] = s.substr(last,white_space - last);
cout << "substring is \"" << s.substr(last,white_space - last) << "\"\n";

but I wouldn't swear that your code doesn't have other bugs in it.

john

Oh so 2nd param in substr() is the length and not where the stop mark
is? Feh what a silly bug :/

I'll check out if I got more errors in my program in a min :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top