|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I have a bunch of strings in a database that have in them a number I
want to extract. Here's the example code I've been working with: AnsiString tmp = "AMjsdfdsdfj 457756 some description"; int firstDelim = 0; int secondDelim = 0; for(int i=0; i<=tmp.Length(); i++) { if(IsDelimiter(" ", tmp, i)); { if ( firstDelim == 0 ) firstDelim = i; else { secondDelim = i; break; } } if ( secondDelim > 0 ) break; } int str_length = secondDelim - firstDelim; ShowMessage(tmp.SubString(firstDelim, str_length)); Can someone give me a hint how to get this to work? Is my code way off, or is there a better way to do it? it's only about 1500 records I need to do this on, so speed is not of greatest importance. Mark |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Feb 5, 11:03am, sparkydarky <markdueck...@gmail.com> wrote:
> I have a bunch of strings in a database that have in them a number I > want to extract. Here's the example code I've been working with: > > AnsiString tmp = "AMjsdfdsdfj 457756 some description"; > int firstDelim = 0; > int secondDelim = 0; > > for(int i=0; i<=tmp.Length(); i++) > { > if(IsDelimiter(" ", tmp, i)); > { > if ( firstDelim == 0 ) > firstDelim = i; > else > { > secondDelim = i; > break; > } > } > if ( secondDelim > 0 ) > break; > } > int str_length = secondDelim - firstDelim; > ShowMessage(tmp.SubString(firstDelim, str_length)); > > Can someone give me a hint how to get this to work? Is my code way > off, or is there a better way to do it? it's only about 1500 records > I need to do this on, so speed is not of greatest importance. > > Mark Without even looking at std::string documentation I can tell you that finding delimiters and subtrings are member functions. Instead of looping, just use those. HTH |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Feb 5, 10:03 am, sparkydarky <markdueck...@gmail.com> wrote:
> I have a bunch of strings in a database that have in them a number I > want to extract. Here's the example code I've been working with: > > AnsiString tmp = "AMjsdfdsdfj 457756 some description"; > int firstDelim = 0; > int secondDelim = 0; > > for(int i=0; i<=tmp.Length(); i++) > { > if(IsDelimiter(" ", tmp, i)); > { > if ( firstDelim == 0 ) > firstDelim = i; > else > { > secondDelim = i; > break; > } > } > if ( secondDelim > 0 ) > break; > } > int str_length = secondDelim - firstDelim; > ShowMessage(tmp.SubString(firstDelim, str_length)); > > Can someone give me a hint how to get this to work? Is my code way > off, or is there a better way to do it? it's only about 1500 records > I need to do this on, so speed is not of greatest importance. > > Mark use a stringstream put what you want to convert into the stringstream using operator << take what you want to convert out of the stringstream and attempt the conversion using operator >> check the fail bit to see if the conversion was successful std::string text = "123"; int number; std::stringstream converter; converter << text; converter >> number; For the "substring" part of your question, use some creativity and remember the effect of whitespace in data being inserted and extracted from an iostream. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
You can try this:-
#include <iostream> #include <sstream> #include <cctype> int main() { std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; int j = 0; std::stringstream cstr; cstr << s; int i = 0; char ch; while( cstr >> ch ) { if( std::isdigit(ch) ) { cstr.putback(ch); break; } if( ( j = s.find(" ",j) )== std::string::npos ) { cstr.seekg(-1); break; } cstr.seekg(++j, std::ios::beg); } if(cstr) { cstr >> i; } std::cout << i; return 0; } With Regards, Reetesh Mukul sparkydarky wrote: > I have a bunch of strings in a database that have in them a number I > want to extract. Here's the example code I've been working with: > > AnsiString tmp = "AMjsdfdsdfj 457756 some description"; > int firstDelim = 0; > int secondDelim = 0; > > for(int i=0; i<=tmp.Length(); i++) > { > if(IsDelimiter(" ", tmp, i)); > { > if ( firstDelim == 0 ) > firstDelim = i; > else > { > secondDelim = i; > break; > } > } > if ( secondDelim > 0 ) > break; > } > int str_length = secondDelim - firstDelim; > ShowMessage(tmp.SubString(firstDelim, str_length)); > > Can someone give me a hint how to get this to work? Is my code way > off, or is there a better way to do it? it's only about 1500 records > I need to do this on, so speed is not of greatest importance. > > Mark |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Feb 5, 12:49 pm, Reetesh Mukul <reetesh.mu...@gmail.com> wrote:
> You can try this:- > > #include <iostream> > #include <sstream> > #include <cctype> > > int main() > { > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > int j = 0; > std::stringstream cstr; > cstr << s; > int i = 0; > char ch; > > while( cstr >> ch ) > { > if( std::isdigit(ch) ) > { > cstr.putback(ch); > break; > } > > if( ( j = s.find(" ",j) )== std::string::npos ) > { > cstr.seekg(-1); > break; > } > > cstr.seekg(++j, std::ios::beg); > > } > > if(cstr) > { > cstr >> i; > } > std::cout << i; > > return 0; > > } > > With Regards, > Reetesh Mukul > > sparkydarky wrote: > > I have a bunch of strings in a database that have in them a number I > > want to extract. Here's the example code I've been working with: > > > AnsiString tmp = "AMjsdfdsdfj 457756 some description"; > > int firstDelim = 0; > > int secondDelim = 0; > > > for(int i=0; i<=tmp.Length(); i++) > > { > > if(IsDelimiter(" ", tmp, i)); > > { > > if ( firstDelim == 0 ) > > firstDelim = i; > > else > > { > > secondDelim = i; > > break; > > } > > } > > if ( secondDelim > 0 ) > > break; > > } > > int str_length = secondDelim - firstDelim; > > ShowMessage(tmp.SubString(firstDelim, str_length)); > > > Can someone give me a hint how to get this to work? Is my code way > > off, or is there a better way to do it? it's only about 1500 records > > I need to do this on, so speed is not of greatest importance. > > > Mark Depending on how he is using the contents, it would be much more efficient to assign the entire thing to the stringstream and keep extracting int type until failbit it set. When it is set, clear it and extract it to string type. Repeat until eof bit is set. The solution you posted may not be useful if the OP actually wants to do something with the non integers.. at least not efficient It may also be error prone if the OP wants to extract strings that contain numbers in them...Example: hello#1 Where as if he knows the text will be used for extracting either text or ints, seperated by whitespace, than he can try to extract an int and extract a string when int extraction fails. That we he is able to use the entire contents in one swoop. Of course, the OP didn't really give specifics. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
sparkydarky <markdueck.bz@gmail.com> wrote:
> I have a bunch of strings in a database that have in them a number I > want to extract. Here's the example code I've been working with: > > AnsiString tmp = "AMjsdfdsdfj 457756 some description"; What is an "AnsiString"? > int firstDelim = 0; > int secondDelim = 0; > > for(int i=0; i<=tmp.Length(); i++) > { What exactly does "IsDelimiter" do? > if(IsDelimiter(" ", tmp, i)); > { > if ( firstDelim == 0 ) > firstDelim = i; > else > { > secondDelim = i; > break; > } > } > if ( secondDelim > 0 ) > break; > } > int str_length = secondDelim - firstDelim; > ShowMessage(tmp.SubString(firstDelim, str_length)); > > Can someone give me a hint how to get this to work? I'm not entirely sure what you think the above should do in the first place. You leave a lot to be assumed... My assumptions: the various parts of the string are separated by at least one space character, that AnsiString can be inserted into a stringstream, and that you only want to extract the first number in the string... There might be some other assumptions I didn't think of. int extractNumber( const string& str ) { int result = 0; stringstream ss( str ); while ( !( ss >> result ) ) { if ( !ss.eof() ) { ss.clear(); ss.ignore( numeric_limits<streamsize>::max(), ' ' ); } else { throw runtime_error( "no number" ); } } return result; } What the code does. Put the string into a stringstream, then attempt to extract a number from it. For as long as we can't extract a number: if we aren't at the end of the stream, clear the stream, scan to the next space, and try again. Otherwise, throw an error indicating that no number was found. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
Reetesh Mukul <reetesh.mukul@gmail.com> wrote:
> You can try this:- > > #include <iostream> > #include <sstream> > #include <cctype> > > int main() > { > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > int j = 0; > std::stringstream cstr; > cstr << s; > int i = 0; > char ch; > > while( cstr >> ch ) > { > if( std::isdigit(ch) ) > { > cstr.putback(ch); > break; > } > From here: > if( ( j = s.find(" ",j) )== std::string::npos ) > { > cstr.seekg(-1); > break; > } > > cstr.seekg(++j, std::ios::beg); to here. Is this block of code necessary? > > } > > if(cstr) > { > cstr >> i; > } > std::cout << i; > > return 0; > } Wouldn't this be a simpler way of doing the same thing? int main() { std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; int i = 0; std::stringstream cstr( s ); char ch = 0; while( cstr >> ch && !isdigit( ch ) ) { } cstr.putback( ch ); cstr >> i; cout << i; } |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Feb 5, 5:03 pm, sparkydarky <markdueck...@gmail.com> wrote:
> I have a bunch of strings in a database that have in them a > number I want to extract. Here's the example code I've been > working with: > AnsiString tmp = "AMjsdfdsdfj 457756 some description"; > int firstDelim = 0; > int secondDelim = 0; > for(int i=0; i<=tmp.Length(); i++) > { > if(IsDelimiter(" ", tmp, i)); > { > if ( firstDelim == 0 ) > firstDelim = i; > else > { > secondDelim = i; > break; > } > } > if ( secondDelim > 0 ) > break; > } > int str_length = secondDelim - firstDelim; > ShowMessage(tmp.SubString(firstDelim, str_length)); > Can someone give me a hint how to get this to work? Not unless you give us a hint about the format of the string, and what determines where you want to look to find the number. > Is my code way off, or is there a better way to do it? Probably. Most of the time, for this sort of thing, boost::regex is the simplest solution. Of course, once you've got the numeric field, you'll have to use std::istringstream to convert it. -- James Kanze (GABI Software) email:james.kanze@gmail.com 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 |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
On Feb 6, 6:35 am, "Daniel T." <danie...@earthlink.net> wrote:
> Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > You can try this:- > > > #include <iostream> > > #include <sstream> > > #include <cctype> > > > int main() > > { > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > int j = 0; > > std::stringstream cstr; > > cstr << s; > > int i = 0; > > char ch; > > > while( cstr >> ch ) > > { > > if( std::isdigit(ch) ) > > { > > cstr.putback(ch); > > break; > > } > > From here: > > if( ( j = s.find(" ",j) )== std::string::npos ) > > { > > cstr.seekg(-1); > > break; > > } > > > cstr.seekg(++j, std::ios::beg); > > to here. Is this block of code necessary? > > > > > } > > > if(cstr) > > { > > cstr >> i; > > } > > std::cout << i; > > > return 0; > > } > > Wouldn't this be a simpler way of doing the same thing? > > int main() > { > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > int i = 0; > std::stringstream cstr( s ); > char ch = 0; > while( cstr >> ch && !isdigit( ch ) ) > { } > cstr.putback( ch ); > cstr >> i; > cout << i; > > } Yes, indeed. |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
On Feb 6, 2:26 am, Christopher <cp...@austin.rr.com> wrote:
> On Feb 5, 12:49 pm, Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > > > > You can try this:- > > > #include <iostream> > > #include <sstream> > > #include <cctype> > > > int main() > > { > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > int j = 0; > > std::stringstream cstr; > > cstr << s; > > int i = 0; > > char ch; > > > while( cstr >> ch ) > > { > > if( std::isdigit(ch) ) > > { > > cstr.putback(ch); > > break; > > } > > > if( ( j = s.find(" ",j) )== std::string::npos ) > > { > > cstr.seekg(-1); > > break; > > } > > > cstr.seekg(++j, std::ios::beg); > > > } > > > if(cstr) > > { > > cstr >> i; > > } > > std::cout << i; > > > return 0; > > > } > > > With Regards, > > Reetesh Mukul > > > sparkydarky wrote: > > > I have a bunch of strings in a database that have in them a number I > > > want to extract. Here's the example code I've been working with: > > > > AnsiString tmp = "AMjsdfdsdfj 457756 some description"; > > > int firstDelim = 0; > > > int secondDelim = 0; > > > > for(int i=0; i<=tmp.Length(); i++) > > > { > > > if(IsDelimiter(" ", tmp, i)); > > > { > > > if ( firstDelim == 0 ) > > > firstDelim = i; > > > else > > > { > > > secondDelim = i; > > > break; > > > } > > > } > > > if ( secondDelim > 0 ) > > > break; > > > } > > > int str_length = secondDelim - firstDelim; > > > ShowMessage(tmp.SubString(firstDelim, str_length)); > > > > Can someone give me a hint how to get this to work? Is my code way > > > off, or is there a better way to do it? it's only about 1500 records > > > I need to do this on, so speed is not of greatest importance. > > > > Mark > > Depending on how he is using the contents, it would be much more > efficient to assign the entire thing to the stringstream and keep > extracting int type until failbit it set. When it is set, clear it and > extract it to string type. Repeat until eof bit is set. > > The solution you posted may not be useful if the OP actually wants to > do something with the non integers.. at least not efficient > It may also be error prone if the OP wants to extract strings that > contain numbers in them...Example: hello#1 > > Where as if he knows the text will be used for extracting either text > or ints, seperated by whitespace, than he can try to extract an int > and extract a string when int extraction fails. That we he is able to > use the entire contents in one swoop. > > Of course, the OP didn't really give specifics. Actually the specification is not there. Indeed, there can be problems in using the code I have posted. |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
On Feb 6, 6:35 am, "Daniel T." <danie...@earthlink.net> wrote:
> Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > You can try this:- > > > #include <iostream> > > #include <sstream> > > #include <cctype> > > > int main() > > { > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > int j = 0; > > std::stringstream cstr; > > cstr << s; > > int i = 0; > > char ch; > > > while( cstr >> ch ) > > { > > if( std::isdigit(ch) ) > > { > > cstr.putback(ch); > > break; > > } > > From here: > > if( ( j = s.find(" ",j) )== std::string::npos ) > > { > > cstr.seekg(-1); > > break; > > } > > > cstr.seekg(++j, std::ios::beg); > > to here. Is this block of code necessary? > > > > > } > > > if(cstr) > > { > > cstr >> i; > > } > > std::cout << i; > > > return 0; > > } > > Wouldn't this be a simpler way of doing the same thing? > > int main() > { > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > int i = 0; > std::stringstream cstr( s ); > char ch = 0; > while( cstr >> ch && !isdigit( ch ) ) > { } > cstr.putback( ch ); > cstr >> i; > cout << i; > > } Actually, I assumed that numeric-digits will appear surrounded by space. This means some thing like {alphabet}*space {digits}+ space({alphabet}*space)*. Your code will extract digits in the following conditions also:- djshdjshj14524 jdhdss Regards, Reetesh Mukul |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
On Feb 6, 6:35 am, "Daniel T." <danie...@earthlink.net> wrote:
> Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > You can try this:- > > > #include <iostream> > > #include <sstream> > > #include <cctype> > > > int main() > > { > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > int j = 0; > > std::stringstream cstr; > > cstr << s; > > int i = 0; > > char ch; > > > while( cstr >> ch ) > > { > > if( std::isdigit(ch) ) > > { > > cstr.putback(ch); > > break; > > } > > From here: > > if( ( j = s.find(" ",j) )== std::string::npos ) > > { > > cstr.seekg(-1); > > break; > > } > > > cstr.seekg(++j, std::ios::beg); > > to here. Is this block of code necessary? > > > > > } > > > if(cstr) > > { > > cstr >> i; > > } > > std::cout << i; > > > return 0; > > } > > Wouldn't this be a simpler way of doing the same thing? > > int main() > { > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > int i = 0; > std::stringstream cstr( s ); > char ch = 0; > while( cstr >> ch && !isdigit( ch ) ) > { } > cstr.putback( ch ); > cstr >> i; > cout << i; > > } Actually, I assumed that numeric-digits will appear surrounded by space. This means some thing like {alphabet}*space {digits}+ space({alphabet}*space)*. Your code will extract digits in the following conditions also:- djshdjshj14524 jdhdss Regards, Reetesh Mukul |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
On Feb 6, 9:27 am, Reetesh Mukul <reetesh.mu...@gmail.com> wrote:
> On Feb 6, 6:35 am, "Daniel T." <danie...@earthlink.net> wrote: > > > > > Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > > You can try this:- > > > > #include <iostream> > > > #include <sstream> > > > #include <cctype> > > > > int main() > > > { > > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > > int j = 0; > > > std::stringstream cstr; > > > cstr << s; > > > int i = 0; > > > char ch; > > > > while( cstr >> ch ) > > > { > > > if( std::isdigit(ch) ) > > > { > > > cstr.putback(ch); > > > break; > > > } > > > From here: > > > if( ( j = s.find(" ",j) )== std::string::npos ) > > > { > > > cstr.seekg(-1); > > > break; > > > } > > > > cstr.seekg(++j, std::ios::beg); > > > to here. Is this block of code necessary? > > > > } > > > > if(cstr) > > > { > > > cstr >> i; > > > } > > > std::cout << i; > > > > return 0; > > > } > > > Wouldn't this be a simpler way of doing the same thing? > > > int main() > > { > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > int i = 0; > > std::stringstream cstr( s ); > > char ch = 0; > > while( cstr >> ch && !isdigit( ch ) ) > > { } > > cstr.putback( ch ); > > cstr >> i; > > cout << i; > > > } > > Actually, I assumed that numeric-digits will appear surrounded by > space. This means some thing like {alphabet}*space {digits}+ > space({alphabet}*space)*. Your code will extract digits in the > following conditions also:- djshdjshj14524 jdhdss > > Regards, > Reetesh Mukul The original code I posted is 'compilable' code in Borland Delphi Studio. My assumptions were that the number would be surrounded by spaces, and actually that the number would be after the first space. AnsiString: The AnsiString data type is used to hold sequences of characters. Each character is an AnsiChar, guaranteed to be 8 bits in size. An AnsiString can hold any number of characters, restricted only by memory. Unlike ShortStrings, AnsiStrings are pointer referenced variables. Storage is allocated for an AnsiString only when needed. For example, assigning the value of one AnsiString to another does not allocate storage for a copy of the first string. Instead, the reference count of the first string is incremented, and the second AnsiString set to point to it. I thought I knew C++ a little, but I realized that I don't because I can barely follow what you guys posted. I tried to put some of the code into Borland C++ Builder, but seems like Borland does not follow the standards very well. Thanks for all your . This will give me really good base to work on and see if I can get it to work. |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
sparkydarky <markdueck.bz@gmail.com> wrote:
> I thought I knew C++ a little, but I realized that I don't because I > can barely follow what you guys posted. I tried to put some of the > code into Borland C++ Builder, but seems like Borland does not follow > the standards very well. Thanks for all your . This will give me > really good base to work on and see if I can get it to work. How about if I add all of the assumed bits? Copy the code below exactly as written and paste it in. See if it compiles. === begin code === #include <limits> #include <sstream> #include <stdexcept> #include <string> int extractNumber( const std::string& str ) { using namespace std; int result = 0; stringstream ss( str ); while ( !( ss >> result ) ) { if ( !ss.eof() ) { ss.clear(); ss.ignore( numeric_limits<streamsize>::max(), ' ' ); } else { throw runtime_error( "no number" ); } } return result; } === end code === |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
Reetesh Mukul <reetesh.mukul@gmail.com> wrote:
> > Actually, I assumed that numeric-digits will appear surrounded by > space. This means some thing like {alphabet}*space {digits}+ > space({alphabet}*space)*. Your code will extract digits in the > following conditions also:- djshdjshj14524 jdhdss I still don't see why you had to make the procedure so complex. Also note, if presented with "5x 7", your code will extract the '5', not the '7'. Your code is emulated pretty well by the code below, which is far simpler: int main() { std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; int result = 0; std::stringstream cstr( s ); char ch = 0; while ( cstr >> ch && !isdigit( ch ) ) cstr.ignore( numeric_limits<streamsize>::max(), ' ' ); cstr.putback( ch ); cstr >> result; cout << result; } |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
On Feb 6, 9:33 pm, "Daniel T." <danie...@earthlink.net> wrote:
> ReeteshMukul <reetesh.mu...@gmail.com> wrote: > > > Actually, I assumed that numeric-digits will appear surrounded by > > space. This means some thing like {alphabet}*space {digits}+ > > space({alphabet}*space)*. Your code will extract digits in the > > following conditions also:- djshdjshj14524 jdhdss > > I still don't see why you had to make the procedure so complex. Also > note, if presented with "5x 7", your code will extract the '5', not the > '7'. > > Your code is emulated pretty well by the code below, which is far > simpler: > > int main() > { > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > int result = 0; > std::stringstream cstr( s ); > char ch = 0; > while ( cstr >> ch && !isdigit( ch ) ) > cstr.ignore( numeric_limits<streamsize>::max(), ' ' ); > cstr.putback( ch ); > cstr >> result; > cout << result; > > } Yes, this is a great solution. Very simple and compact solution. Regards, Reetesh Mukul |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
On Feb 6, 7:30 pm, Reetesh Mukul <reetesh.mu...@gmail.com> wrote:
> On Feb 6, 9:33 pm, "Daniel T." <danie...@earthlink.net> wrote: > > ReeteshMukul <reetesh.mu...@gmail.com> wrote: > > > Actually, I assumed that numeric-digits will appear > > > surrounded by space. This means some thing like > > > {alphabet}*space {digits}+ space({alphabet}*space)*. Your > > > code will extract digits in the following conditions > > > also:- djshdjshj14524 jdhdss > > I still don't see why you had to make the procedure so > > complex. Also note, if presented with "5x 7", your code will > > extract the '5', not the '7'. > > Your code is emulated pretty well by the code below, which is far > > simpler: > > int main() > > { > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > int result = 0; > > std::stringstream cstr( s ); > > char ch = 0; > > while ( cstr >> ch && !isdigit( ch ) ) > > cstr.ignore( numeric_limits<streamsize>::max(), ' ' ); > > cstr.putback( ch ); > > cstr >> result; > > cout << result; > > } > Yes, this is a great solution. Very simple and compact solution. It fails if the separator is a tab, rather than a space. -- James Kanze (GABI Software) email:james.kanze@gmail.com 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 |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
James Kanze <james.kanze@gmail.com> wrote:
> Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > "Daniel T." <danie...@earthlink.net> wrote: > > > ReeteshMukul <reetesh.mu...@gmail.com> wrote: > > > > > > > Actually, I assumed that numeric-digits will appear > > > > surrounded by space. > > > > > > I still don't see why you had to make the procedure so > > > complex. > > > > > > Your code is emulated by the code below, which is far simpler: > > > > > > int main() > > > { > > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > > > > int result = 0; > > > std::stringstream cstr( s ); > > > char ch = 0; > > > while ( cstr >> ch && !isdigit( ch ) ) > > > cstr.ignore( numeric_limits<streamsize>::max(), ' ' ); > > > cstr.putback( ch ); > > > cstr >> result; > > > cout << result; > > > } > > > Yes, this is a great solution. Very simple and compact solution. > > It fails if the separator is a tab, rather than a space. The code has lots of assumptions and it fails if any of them don't hold, that's not the point. The question I asked Reetesh was why he had such a complex solution when the above solution, which is far simpler, does the exact same thing. I'm guessing that it was because he didn't know about the 'ignore()' member-function, and didn't know that the putback and op>> would do the "right thing" if the stream failed. |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
On Feb 7, 5:20 pm, "Daniel T." <danie...@earthlink.net> wrote:
> James Kanze <james.ka...@gmail.com> wrote: > > Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > > "Daniel T." <danie...@earthlink.net> wrote: > > > > ReeteshMukul <reetesh.mu...@gmail.com> wrote: > > > > > > Actually, I assumed that numeric-digits will appear > > > > > surrounded by space. > > > > > I still don't see why you had to make the procedure so > > > > complex. > > > > > Your code is emulated by the code below, which is far simpler: > > > > > int main() > > > > { > > > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > > > int result = 0; > > > > std::stringstream cstr( s ); > > > > char ch = 0; > > > > while ( cstr >> ch && !isdigit( ch ) ) > > > > cstr.ignore( numeric_limits<streamsize>::max(), ' ' ); > > > > cstr.putback( ch ); > > > > cstr >> result; > > > > cout << result; > > > > } > > > > Yes, this is a great solution. Very simple and compact solution. > > > It fails if the separator is a tab, rather than a space. > > The code has lots of assumptions and it fails if any of them don't hold, > that's not the point. > > The question I asked Reetesh was why he had such a complex solution when > the above solution, which is far simpler, does the exact same thing. I'm > guessing that it was because he didn't know about the 'ignore()' > member-function, and didn't know that the putback and op>> would do the > "right thing" if the stream failed. Yes, you are right Daniel. I indeed didn't knew about 'ignore()' and putback,op's mechanism after things fail. Now an obvious question is popping in my mind, will it not be good to have predicates( functors ) in ignore function (or similar functions) ? Regards, Reetesh Mukul |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
On Feb 7, 2:33 pm, Reetesh Mukul <reetesh.mu...@gmail.com> wrote:
> On Feb 7, 5:20 pm, "Daniel T." <danie...@earthlink.net> wrote: > > James Kanze <james.ka...@gmail.com> wrote: > > > Reetesh Mukul <reetesh.mu...@gmail.com> wrote: > > > > "Daniel T." <danie...@earthlink.net> wrote: > > > > > ReeteshMukul <reetesh.mu...@gmail.com> wrote: > > > > > > Actually, I assumed that numeric-digits will appear > > > > > > surrounded by space. > > > > > I still don't see why you had to make the procedure so > > > > > complex. > > > > > Your code is emulated by the code below, which is far simpler: > > > > > int main() > > > > > { > > > > > std::string s = "dsdhjsahdk dsdjdsaj 36782367 sdjdhak"; > > > > > > int result = 0; > > > > > std::stringstream cstr( s ); > > > > > char ch = 0; > > > > > while ( cstr >> ch && !isdigit( ch ) ) > > > > > cstr.ignore( numeric_limits<streamsize>::max(), ' ' ); > > > > > cstr.putback( ch ); > > > > > cstr >> result; > > > > > cout << result; > > > > > } > > > > Yes, this is a great solution. Very simple and compact solution. > > > It fails if the separator is a tab, rather than a space. > > The code has lots of assumptions and it fails if any of them > > don't hold, that's not the point. Yes and no. IMHO, the point is that this is generally not a good way to parse input. The ignore function is not flexible enough to be generally of much use other than for resynchronizing the input after an error (and even then, only with very simple formats). > > The question I asked Reetesh was why he had such a complex > > solution when the above solution, which is far simpler, does > > the exact same thing. I'm guessing that it was because he > > didn't know about the 'ignore()' member-function, and didn't > > know that the putback and op>> would do the "right thing" if > > the stream failed. > Yes, you are right Daniel. I indeed didn't knew about > 'ignore()' and putback,op's mechanism after things fail. Now > an obvious question is popping in my mind, will it not be good > to have predicates( functors ) in ignore function (or similar > functions) ? Probably because that's not its role. But it's an interesting suggestion---it should be possible to define a manipulator which skips using a predicate. More useful, probably, would be a manipulator which skips using a regular expression. This would be far from trivial with extended regular expressions, like Boost (which requires at least a forward iterator, since backtracking is necessary), but wouldn't be too hard with my regular expression class, which doesn't support any of the extensions, but will work with input iterators. -- James Kanze (GABI Software) email:james.kanze@gmail.com 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 |
|
|
|
#21 |
|
Messages: n/a
Hébergeur: |
On 2008-02-05 11:03:18 -0500, sparkydarky <markdueck.bz@gmail.com> said:
> I have a bunch of strings in a database that have in them a number I > want to extract. Why not try to solve it at the source? At the database. If Oracle, try select to_number( replace( translate(COL, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW XYZ ', rpad('#',26+26+1,'#')) , '#')) as COL from TABLE; > [...] -- // kira |
|
|
|
#22 |
|
|