subst() and fin() help needed

Hi, I am a hard time "parsing" string data from a string variable to a string array. I cannot use the sstream members.

the output of code[] should be the same as the sentence variable,but it's not.
can you please help?
Thanks.
#include<iostream>
#include<string>
#include<cstring>

using namespace std;


int main(){

string sentence="... .- ...- . ..-- ..-. ..- -.";

string code[50];

int n=0; int m = sentence.find(' ');
int i=0;
while(m != -1)
{code[i]=sentence.substr(n,m);

n= m+1;
m=sentence.find(' ',m+1);
++i;
} 
cout<<code;



return 0;}

Open in new window

pgmerLAAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

phoffric\Commented:
Ok, space is a delimiter.
When you use find in a loop, you need to keep track of the startPos for each pass.
You can avoid having two find's by initializing startPos to a good value. This way only one find will be in the loop:

sentence.find(' ', startPos );

Print out the values of n and m in each pass.

0
phoffric\Commented:
BTW - since you are splitting the string into a number of tokens, why not define a split function which you will be able to use over again. Then instead of having an array of strings (i.e., your code array), you could use vector<string> so that you don't have to know in advance how many tokens are in your sentence.

Here is a nice discussion of how to split a string into tokens.
    http://www.experts-exchange.com/Programming/Languages/CPP/Q_24600272.html
0
pgmerLAAuthor Commented:
we haven't done vectors in class yet.
I am still have a hard time with startPos.

I don't know how to improve my code.
I printed the value of n and m and based on the output, I still don't understand why my code doesn't work.
0
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

phoffric\Commented:
Ok, then your array, code[50] is fine for now. I realize this is very tricky code.

Your definition of startPos should be intialized to 0.

Show your code with debug that identifies: the two arguments to substr and the resultant token that you find. And show the output.
0
phoffric\Commented:
BTW - to use just one find, you could incorporate the find in the while test condition and test for string::npos (which is -1). If you do this, be very careful with parenthesis.
    http://www.cplusplus.com/reference/string/string/find/
    http://www.cplusplus.com/reference/string/string/npos/
0
phoffric\Commented:
Take a closer look at substr
     http://www.cplusplus.com/reference/string/string/substr/
string substr ( size_t pos = 0, size_t n = npos ) const;

"n = Length of the substring."

But you say:
    substr(n,m);

where m = sentence.find(...);

Now, take a closer look at the find link which says that the return value is "The position of the first occurrence in the string of the searched content."

Do you see the problem. You are using a position in substr instead of the length.
0
pgmerLAAuthor Commented:
Here is what I wrote.

It's a lot more difficult than I thought.
Are you gonna be online for a while?

what am I missing?
#include<iostream>
#include<string>
using namespace std;

int main(){

string sentence="... .- ...- . ..-- ..-. ..- -.";
string code[50];
string word="";

int startPos=0;
int n=0;

while(startPos !=-1)
{n= sentence.find(' ', startPos+1);
word=sentence.substr(startPos,n);
cout<<"1st substr arg: "<<startPos
<<"2nd substr arg: "<<n
<<" and the token : "<<word;
cout<<endl;
startPos=n;
}

return 0;}

Open in new window

0
pgmerLAAuthor Commented:
what do you think of my new code?
#include<iostream>
#include<string>
using namespace std;

int main(){


string sentence="... .- ...- . ..-- ..-. ..- -.";
string code[50];
string word="";

int n = 0; int m=0;
int i =0;

while(m !=-1)
{
m = sentence.find(' ', n+1);
word = sentence.substr( n, m);
code[i]=word;
word.erase();
++i;
n=m;
}
for (int i =0; i<30; ++i)
{cout<<code[i]<<" ";}


return 0;}

Open in new window

0
phoffric\Commented:
I've run the code in http:#35339611 - here's the output
1st substr arg: 0  2nd substr arg: 3    and the token : ...
1st substr arg: 3  2nd substr arg: 6    and the token :  .- ..
1st substr arg: 6  2nd substr arg: 11    and the token :  ...- . ..-
1st substr arg: 11  2nd substr arg: 13    and the token :  . ..-- ..-.
1st substr arg: 13  2nd substr arg: 18    and the token :  ..-- ..-. ..- -.
1st substr arg: 18  2nd substr arg: 23    and the token :  ..-. ..- -.
1st substr arg: 23  2nd substr arg: 27    and the token :  ..- -.
1st substr arg: 27  2nd substr arg: -1    and the token :  -.

Open in new window

Let's start with the 2nd substr arg. It starts out just fine with a value of 3, and the token looks good.

But the next token is only two chars (i.e., the length of the second token). Yet your 2nd arg to substr is 6, and then continues to increase. As mentioned in my previous post, the 2nd arg to sbustr is the length of the token you wish to extract.
int main(){  
    string sentence="... .- ...- . ..-- ..-. ..- -.";  
    string code[50]; 
    int numTokens = split( sentence , code );

    for( int i=0; i < numTokens; ++i ) {
        cout << code[i] <<endl;
    }
}

Open in new window

0
phoffric\Commented:
BTW - I wrote an 8 line split function, which seems to come up often enough that I thought I'd save it. (In fact, in VS 2010 managed C++ code, it is a built-in function.) Here's the usage:
int main(){ 
    string sentence="... .- ...- . ..-- ..-. ..- -.";  
    string code[50]; 
    int numTokens = split( sentence , code );

    for( int i=0; i < numTokens; ++i ) {
        cout << code[i] <<endl;
    }
}

Open in new window

And the output is:
...
.-
...-
.
..--
..-.
..-
-.

Open in new window

I took a quick look at your code in http:#35339667 and immediately gravitated to the output of find and the 2nd argument of substr. Looks like the issue noted has not been resolved.

How about creating a temporary variable, called tokenLength, and use that variable as the 2nd argument of substr. That may make the issue more transparent. (And that would be a nice variable to print out in your debug version.)
0
pgmerLAAuthor Commented:
we haven't done split function in class yet. So I won't be able to use it.
0
phoffric\Commented:
There is no split function. I just wrote one myself for its useful utility. You don't have to do that if you are not supposed to write functions other than main.
0
phoffric\Commented:
I'll be leaving shortly. I'll be able to help further tomorrow. But, actually, the primary issues has been discussed. There may be some boundary issues remaining. But that should be relatively easy.

Do you understand the primary issue about the 2nd argument to substr?
0
pgmerLAAuthor Commented:
I got it. Thanks a lot phoffric:

word = sentence.substr( n, m-n);
#include<iostream>
#include<string>
using namespace std;

int main(){


string sentence="... .- ...- . ..-- ..-. ..- -.";
string code[50];
string word="";

int n = 0; int m=0;
int i =0;

while(m !=-1)
{
m = sentence.find(' ', n);
word = sentence.substr( n, m-n);
code[i]=word;
word.erase();
++i;
n=m+1;
}
for (int i =0; i<30; ++i)
{cout<<code[i]<<" ";}


return 0;}

Open in new window

0
phoffric\Commented:
Just ready to log out when I saw the light bulb glow brighter :)

I did mention that it would be tricky in a previous question. You just have to read every word in the references extraordinarily carefully.

BTW - I don't think you need the erase.
BTW - When using cout, it's good practice to flush the buffer with an endl, just to be safe.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
phoffric\Commented:
See you in another question. Have a good night.
0
pgmerLAAuthor Commented:
Thank your for you patience.
Have a good night too.
0
phoffric\Commented:
You are welcome. And now I have my split function which I've been meaning to write :)

One thing though about closing your questions. It is really important that you choose a post (or more) that truly reflect the best help given. When non-member searchers google this type of question, they will be able to see the accepted answer.

When EE members use the EE search engine, they will naturally gravitate towards the Accepted answer, and if it doesn't immediately seem to address the core issues, then they move on.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.