Re: Newbie question on strings
James Kanze <james.kanze@gmail.com> wrote:
"Daniel T." <danie...@earthlink.net> wrote:
Very good, but...
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;
bool is_digit( char c )
{
return isdigit( c );
Where is isdigit defined. There are isdigit functions defined
in two different standard headers; you didn't include either of
them, and the call here is legal with none of them, it's either:
#include <locale>
// ...
return std::isdigit( c, std::locale() ) ;
or
#include <ctype.h>
// ...
return isdigit( static_cast< unsigned char >( c ) ) ;
Given the way you've written it, why write it at all?
The missing include was an oops on my part, apparently it is included
through one of the others on my system. As for the cast to unsigned
char, I feel it is completely unnecessary in this case (I did consider
it.) The only thing at issue is if 'c' is negative and how that will
expand out to an int. If you actually tested isdigit( c ) with isdigit(
static_cast<unsigned char>( c ) ) for all values of 'c', I expect you
will find that the return values are the same in every case. (In looking
around, this may not be true for EBCDIC.)
}
int main()
{
string input;
getline( cin, input );
I'd check that the read succeeded, just to be sure.
I considered it, but didn't find it necessary. If getline fails, input's
value will be unchanged (i.e. empty.) Unless the original requirements
stated that something special had to be done on failure, I see no reason
for it.
const string::iterator it =
stable_partition( input.begin(), input.end(), &is_digit );
In theory, you could use the two argument version of
std::isdigit directly in the call here, by means of ptr_fun and
bind2nd. But since these are all templates, as is the two
argument function, you'd have to explicitly tell the compiler
which instantiation to use. The resulting expression is not
particularly succinct.
I'm interested. I've attempted to do this several times but have been
unable to figure out the syntax. Care to elaborate?
cout << "x = ";
copy( input.begin(), it, ostream_iterator<char>( cout ) );
cout << "\ny = ";
copy( it, input.end(), ostream_iterator<char>( cout ) );
(You forgot the final newline.)
No, I didn't. I found it unnecessary.
I'd probably write this:
cout << "x = " << std::string( input.begin(), it ) << '\n' ;
cout << "y = " << std::string( it, input.end() ) << '\n' ;
It's probably less efficient this way, but IMHO considerably
more readable.
That's a good question. Is it less efficient? I like your use of the
string constructor instead of using copy.
}
I do like your use of a standard algorithm.
Why reinvent the wheel?