 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
electrixnow Guest
|
Posted: Tue Feb 07, 2006 1:00 pm Post subject: help parsing strings |
|
|
in MS VC++ Express I need to know how to get from one comma delimited
text string to many strings.
from this:
main_string = "onE,Two,Three , fouR,five, six "
to these:
string1 = "one"
string2 = "two"
string3 = "three"
string4 = "four"
string5 = "five"
string6 = "six"
the white space needs to be removed and the case needs to be all upper
or lower.
The result needs to be strings and not pointers or addresses in memory
so I can test:
I have it working but I have pointers for strings and can't convert
them back to strings.
string test = "three";
if (three == "three")
some getlines will only have two strings some may have up to 10
Please help with examples, you input with exact syntax is greatly
appreciated
I have been struggling with not using pointers but every time I end up
using them.
Thanks in advance
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Wed Feb 08, 2006 11:00 am Post subject: Re: help parsing strings |
|
|
electrixnow wrote:
| Quote: | in MS VC++ Express I need to know how to get from one comma delimited
text string to many strings.
|
#include <cctype>
#include <iostream>
#include <ostream>
#include <string>
#include <vector>
typedef std::vector<std::string> stringvec;
void parse(std::string in, stringvec &out) {
// Erase all entries from the vector
out.swap(stringvec());
int begin=0, end=-1;
while (end < int(in.length())) {
// Find the next token
begin = end+1;
while (' '==in[begin])
++begin; // Skip leading whitespace
end = in.find(',',begin+1);
if (-1==end) end=in.length();
// Skip trailing whitespace
int realend=end;
while (realend>begin && in[realend-1]==' ')
--realend;
// Convert the string to lowercase
std::string x = in.substr(begin, realend-begin);
int xlen = x.length();
for (int i=0; i<xlen; ++i)
x[i] = std::tolower(x[i]);
// Add the string to the vector
out.push_back(x);
}
}
int main() {
stringvec x;
parse("onE,Two,Three , fouR,five, six ",x);
int size = x.size();
for (int i=0; i<size; ++i)
std::cout << i << ": \"" << x[i] << "\"\n";
std::cout << "Fin" << std::endl;
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Wed Feb 08, 2006 11:00 am Post subject: Re: help parsing strings |
|
|
In article <1139291709.676285.84150 (AT) o13g2000cwo (DOT) googlegroups.com>,
electrixnow <info...@charter.net> wrote:
| Quote: | in MS VC++ Express I need to know how to get from one comma delimited
text string to many strings.
from this:
main_string = "onE,Two,Three , fouR,five, six "
to these:
string1 = "one"
string2 = "two"
string3 = "three"
string4 = "four"
string5 = "five"
string6 = "six"
the white space needs to be removed and the case needs to be all upper
or lower.
The result needs to be strings and not pointers or addresses in memory
so I can test:
I have it working but I have pointers for strings and can't convert
them back to strings.
string test = "three";
if (three == "three")
some getlines will only have two strings some may have up to 10
Please help with examples, you input with exact syntax is greatly
appreciated
I have been struggling with not using pointers but every time I end up
using them.
what do you want from "one , , two three"? |
A)
string1 = "one";
string2 = "";
string3 = "two";
string4 = "three"
or
B)
string1 ="one";
string2 ="two";
string3 ="three":
or
C)
something else
now if A then we are just tokenizing with whitespace or ',' and is
handled in by various methods such as a token iterator provided by
boost.
if B then you need to tokenize with a comma and then tokenize the result
with whitespace as the delimiter. again a token iterator provided by
boost is one solution.
if C need more details...
the above are not the only solutions but the easiest to state.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Sumit Rajan Guest
|
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Wed Feb 08, 2006 8:10 pm Post subject: Re: help parsing strings |
|
|
| Quote: | electrixnow <info...@charter.net> wrote:
in MS VC++ Express I need to know how to get from one comma delimited
text string to many strings.
|
Carl Barron wrote:
| Quote: | what do you want from "one , , two three"?
A)
string1 = "one";
string2 = "";
string3 = "two";
string4 = "three"
or
B)
string1 ="one";
string2 ="two";
string3 ="three":
or
C)
something else
|
I think his first statement answers this question... "comma delimited".
So the answer is A.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Seungbeom Kim Guest
|
Posted: Mon Feb 13, 2006 7:06 am Post subject: Re: help parsing strings |
|
|
Allan W wrote:
| Quote: |
typedef std::vector<std::string> stringvec;
void parse(std::string in, stringvec &out) {
// Erase all entries from the vector
out.swap(stringvec());
|
I'm just curious: why out.swap(stringvec()) instead of out.clear()?
Is it better in any way?
--
Seungbeom Kim
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Joe Guest
|
Posted: Mon Feb 13, 2006 3:06 pm Post subject: Re: help parsing strings |
|
|
Seungbeom Kim wrote:
| Quote: | I'm just curious: why out.swap(stringvec()) instead of out.clear()?
Is it better in any way?
|
out.clear() doesn't free any memory allocated to the vector itself. In
other words, if you had 100 strings in the vector, a clear would
destroy all those strings and reset the size to 0, but there would
still be space reserved for those 100 string objects. The swap() idiom
not only causes the vector to free the objects stored in it, but it
also frees up any memory reserved for the vector itself. This is also
a handy idiom for various implementations of a hash_map or hash_set
where you may get a significant chunk of memory reserved to the
collection that won't get returned to the OS via clear().
As with any idiom, the value depends upon how big a problem the
unreclaimed memory might be versus the unobviousness of the idiom.
Once folks get used to seeing it, the latter factor becomes less and
less.
joe
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Seungbeom Kim Guest
|
Posted: Tue Feb 14, 2006 1:06 am Post subject: Re: help parsing strings |
|
|
Joe wrote:
| Quote: | Seungbeom Kim wrote:
I'm just curious: why out.swap(stringvec()) instead of out.clear()?
Is it better in any way?
out.clear() doesn't free any memory allocated to the vector itself. In
other words, if you had 100 strings in the vector, a clear would
destroy all those strings and reset the size to 0, but there would
still be space reserved for those 100 string objects. The swap() idiom
not only causes the vector to free the objects stored in it, but it
also frees up any memory reserved for the vector itself.
|
I see, thanks. Now I remember seeing this idiom before. :)
| Quote: | As with any idiom, the value depends upon how big a problem the
unreclaimed memory might be versus the unobviousness of the idiom.
Once folks get used to seeing it, the latter factor becomes less and
less.
|
I don't think the unreclaimed memory would be a big problem, especially
if more items would be added soon later as in the Allan's example.
Often when you have to start by clearing a vector given as an argument,
you can make the interface clearer by using a locally defined vector and
returning it later:
// #1
void parse(std::string in, stringvec &out) {
// Erase all entries from the vector
out.swap(stringvec());
// Fill out
}
// #2
stringvec parse(std::string in) {
stringvec out;
// Fill out
return out;
}
--
Seungbeom Kim
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Tue Feb 14, 2006 5:06 pm Post subject: Re: help parsing strings |
|
|
Seungbeom Kim wrote:
| Quote: | Often when you have to start by clearing a vector given as an argument,
you can make the interface clearer by using a locally defined vector and
returning it later:
// #1
void parse(std::string in, stringvec &out) {
// Erase all entries from the vector
out.swap(stringvec());
// Fill out
}
// #2
stringvec parse(std::string in) {
stringvec out;
// Fill out
return out;
}
|
This returns the entire vector by value. NVRO could cause the copy to
be
skipped... but compilers that don't implement this optimization could
copy the entire vector and every element in the vector.
Yes, yes, premature optimization and all that... but optimization is
much
easier if you can avoid changing the function signature. In #2 the
vector
is a return value. If profiling showed that it was important to change
to
#1 for performance reasons, then depending on how often the function
was called, this change could be quite painful.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Eugene Kalenkovich Guest
|
Posted: Wed Feb 15, 2006 2:06 pm Post subject: Re: help parsing strings |
|
|
"Allan W" <allan_w@my-dejanews.com> wrote in message
news:1139334963.068333.15180 (AT) g43g2000cwa (DOT) googlegroups.com...
| Quote: | // Erase all entries from the vector
out.swap(stringvec());
|
Does it work? For what compiler/version? The last one that allowed this
construct that I am aware of was VC 6.0
-- EK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Thu Feb 16, 2006 2:06 am Post subject: Re: help parsing strings |
|
|
| Quote: | "Allan W" <allan_w@my-dejanews.com> wrote
// Erase all entries from the vector
out.swap(stringvec());
|
Eugene Kalenkovich wrote:
| Quote: | Does it work? For what compiler/version? The last one that allowed this
construct that I am aware of was VC 6.0
|
As far as I know, this is a standard idiom. I tested it on .Net 2003,
and it sure seems to work, as verified by out.capacity().
What compiler/version does this NOT work on?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Sat Feb 18, 2006 1:06 am Post subject: Re: help parsing strings |
|
|
Allan W wrote:
| Quote: | "Allan W" <allan_w@my-dejanews.com> wrote
// Erase all entries from the vector
out.swap(stringvec());
Eugene Kalenkovich wrote:
Does it work? For what compiler/version? The last one that
allowed this construct that I am aware of was VC 6.0
As far as I know, this is a standard idiom. I tested it on
.Net 2003, and it sure seems to work, as verified by
out.capacity().
What compiler/version does this NOT work on?
|
It shouldn't compile on a standard conforming compiler; it
requires binding a temporary to a non-const reference.
The *standard* idiom is to use swap, either the reverse:
stringvec().swap( out ) ;
or to use an explicit temporary:
stringvec empty ;
out.swap( empty ) ;
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Eugene Kalenkovich Guest
|
Posted: Sat Feb 18, 2006 1:06 am Post subject: Re: help parsing strings |
|
|
"Allan W" <allan_w@my-dejanews.com> wrote in message
news:1140034430.302925.253230 (AT) o13g2000cwo (DOT) googlegroups.com...
| Quote: | "Allan W" <allan_w@my-dejanews.com> wrote
// Erase all entries from the vector
out.swap(stringvec());
Eugene Kalenkovich wrote:
Does it work? For what compiler/version? The last one that allowed this
construct that I am aware of was VC 6.0
As far as I know, this is a standard idiom. I tested it on .Net 2003,
and it sure seems to work, as verified by out.capacity().
What compiler/version does this NOT work on?
On any standard-compliant compiler. Even MS, AFAIR since 2003 version, gives |
a warning (on level 4) that this conversion is not standard-compliant.
Swap (STL swaps, you can define your own differently, though other
signatures make no sense) accepts non-const reference; it means that only
lvalue can be accepted.
-- EK
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
electrixnow Guest
|
Posted: Sat Feb 18, 2006 5:06 am Post subject: Re: help parsing strings |
|
|
You replied on parsing strings. I have a problem with code that
follows. it only returns
4 for the sizeof &tokens. Why?
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void Tokenize(const string& str,
vector<string>& tokens,
const string& delimiters = " ,\t\n")
{
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
int main()
{
vector<string> tokens;
string str(";1,2,3,4,5,6,7,8,9,0"); // replace with getline
string start = str.substr(0,1);
if(start == ";")cout<<"HELLO WORLD"<<'\n'; // skip this line for
comments
int len = str.length();
for (int a=0; a<len; ++a)
str[a]=toupper(str[a]);
Tokenize(str, tokens);
for (int i=0;i<sizeof(&tokens);++i){ // check amount of tokens
cout << tokens[i]<<'\n';
}
}
Thanks,
Grant
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Sat Feb 18, 2006 5:06 am Post subject: Re: help parsing strings |
|
|
In article <1140034430.302925.253230 (AT) o13g2000cwo (DOT) googlegroups.com>,
Allan W <allan_w@my-dejanews.com> wrote:
| Quote: | "Allan W" <allan_w@my-dejanews.com> wrote
// Erase all entries from the vector
out.swap(stringvec());
Eugene Kalenkovich wrote:
Does it work? For what compiler/version? The last one that allowed this
construct that I am aware of was VC 6.0
As far as I know, this is a standard idiom. I tested it on .Net 2003,
and it sure seems to work, as verified by out.capacity().
What compiler/version does this NOT work on?
Should NOT work on any compliant compiler, swap wants a non-constant |
referenece and conversion of a temporary [stringvec()] to a non
constant reference is the no-no. but
{
stringvec t;
out.swap(t);
}
is just fine.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|