Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Reverse a String

Reply
Thread Tools

Reverse a String

 
 
arnuld
Guest
Posts: n/a
 
      10-05-2007
PURPOSE: This program asks the user to input words and then it
prints all of them in the same order but each word is reversed. e.g.
INPUT -> C++ Bjarne
OUTPUT -> ++C enrajB
*/

PROBLEM: I am not able to reverse the individual strings

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>


int main()
{
std::vector<std::string> svec;

std::copy( std::istream_iterator<std::string>( std::cin ),
std::istream_iterator<std::string>(),
std::back_inserter( svec ) );



/* prints the vector to standard output */
std::cout << "\n------------------------------------\n";
std::copy( svec.begin(), svec.end(),
std:stream_iterator<std::string>( std::cout, "\n" ) );

return 0;
}

========= OUTPUT ==============
~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra reverse-input.cpp
~/programming/c++ $ ./a.out
C++ Bjarne

------------------------------------
C++
Bjarne
~/programming/c++ $


I tried to use "reverse_copy" in place of 1st std::copy:

std::reverse_copy( std::istream_iterator<std::string>( std::cin ),
std::istream_iterator<std::string>(),
std::back_inserter(svec ) );


but it raises compile-time error:

~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra reverse-input.cpp
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/stl_algo.h:
In function ‘_OutputIterator std::reverse_copy(_BidirectionalIterator,
_BidirectionalIterator,
:_OutputIterator) [with _BidirectionalIterator =
std::istream_iterator<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, char, std::char_traits<char>, long int>,
_OutputIterator =
std::back_insert_iterator<std::vector<std::basic_s tring<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > > > >]’:
reverse-input.cpp:22: instantiated from here
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/stl_algo.h:1722:
error: no match for ‘operato\ r--’ in ‘--__last’ ~/programming/c++
$


-- arnuld
http://lispmachine.wordpress.com

 
Reply With Quote
 
 
 
 
Barry
Guest
Posts: n/a
 
      10-05-2007
arnuld wrote:
>
> I tried to use "reverse_copy" in place of 1st std::copy:
>
> std::reverse_copy( std::istream_iterator<std::string>( std::cin ),
> std::istream_iterator<std::string>(),
> std::back_inserter(svec ) );
>
>


reverse_copy need the input to be BidirectionalIterator, while
istream_iterator is of ForwardIterator
 
Reply With Quote
 
 
 
 
Gianni Mariani
Guest
Posts: n/a
 
      10-05-2007
arnuld wrote:
> PURPOSE: This program asks the user to input words and then it
> prints all of them in the same order but each word is reversed. e.g.
> INPUT -> C++ Bjarne
> OUTPUT -> ++C enrajB
> */
>
> PROBLEM: I am not able to reverse the individual strings


Why not use std::reverse() ?
 
Reply With Quote
 
=?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
Guest
Posts: n/a
 
      10-05-2007
On 2007-10-05 13:34, arnuld wrote:
> PURPOSE: This program asks the user to input words and then it
> prints all of them in the same order but each word is reversed. e.g.
> INPUT -> C++ Bjarne
> OUTPUT -> ++C enrajB
> */
>
> PROBLEM: I am not able to reverse the individual strings


You can always iterate over the characters in each string using a
reverse iterator, unless you actually reverse the words read in as
Gianni Mariani suggested.

--
Erik Wikström
 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      10-05-2007
> On Fri, 05 Oct 2007 22:03:24 +1000, Gianni Mariani wrote:

> Why not use std::reverse() ?


tried that but that raises an error:


int main()
{
std::vector<std::string> svec;

std::reverse_copy( std::istream_iterator<std::string>( std::cin ),
std::istream_iterator<std::string>(),
std::back_inserter( svec ) );


std::reverse( svec.begin(), svec.end() );

/* prints the vector to standard output */
std::cout << "\n------------------------------------\n";
std::copy( svec.begin(), svec.end(),
std:stream_iterator<std::string>( std::cout, "\n" ) );

return 0;
}


~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra reverse-input.cpp
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/stl_algo.h: In function ‘_OutputIterator std:\
:reverse_copy(_BidirectionalIterator, _BidirectionalIterator, _OutputIterator) [with _BidirectionalIterator = std::istream_i\
terator<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, char, std::char_traits<char>, long int>, _Ou\
tputIterator = std::back_insert_iterator<std::vector<std::basic_s tring<char, std::char_traits<char>, std::allocator<char> >,\
std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]’:
reverse-input.cpp:22: instantiated from here
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/stl_algo.h:1722: error: no match for ‘operato\
r--’ in ‘--__last’
~/programming/c++ $



-- arnuld
http://lispmachine.wordpress.com

 
Reply With Quote
 
Jerry Coffin
Guest
Posts: n/a
 
      10-05-2007
In article <(E-Mail Removed)>,
http://www.velocityreviews.com/forums/(E-Mail Removed) says...

[ ... ]

> PROBLEM: I am not able to reverse the individual strings


Yet!

> #include <iostream>
> #include <string>
> #include <vector>
> #include <algorithm>
> #include <iterator>
>
>
> int main()
> {
> std::vector<std::string> svec;
>
> std::copy( std::istream_iterator<std::string>( std::cin ),
> std::istream_iterator<std::string>(),
> std::back_inserter( svec ) );


Now you have a vector of strings. The next step is to step through the
vector and reverse each one.

> /* prints the vector to standard output */
> std::cout << "\n------------------------------------\n";
> std::copy( svec.begin(), svec.end(),
> std:stream_iterator<std::string>( std::cout, "\n" ) );
>
> return 0;
> }


[ ... ]

> I tried to use "reverse_copy" in place of 1st std::copy:


The two iterators specifying the input to reverse_copy are required to
be bidirectional iterators, and an istream_iterator isn't a
bidirectional iterator. In C++ 0x, when we get concepts, it'll be
possible to encode requirements like this directly, to allow a much more
informative error message (interestingly, as I understand things, this
problem with error messages was one of the original motivations for the
work that resulted in the concepts proposal).

In any case, it wouldn't really do any good if it did work. You could
(for example) use reverse_copy in place of the _second_ copy quite
easily (vector iterators are random-access iterators, which are a
superset of bidirectional iterators) but it would just copy the strings
in reverse order, leaving each individual string unaffected.

I'd carry out the operation in three steps: read in the strings, then
reverse them, then write them out. You've got the reading and writing
done. The obvious way to reverse them (at least to me) would be a
functor that produces a reversed copy of an individual string, and
std::transform to apply that to the whole vector.

--
Later,
Jerry.

The universe is a figment of its own imagination.
 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      10-05-2007
> On Fri, 05 Oct 2007 07:49:47 -0600, Jerry Coffin wrote:

> The two iterators specifying the input to reverse_copy are required to
> be bidirectional iterators, and an istream_iterator isn't a
> bidirectional iterator. In C++ 0x, when we get concepts, it'll be
> possible to encode requirements like this directly, to allow a much more
> informative error message (interestingly, as I understand things, this
> problem with error messages was one of the original motivations for the
> work that resulted in the concepts proposal).


got that


> In any case, it wouldn't really do any good if it did work. You could
> (for example) use reverse_copy in place of the _second_ copy quite
> easily (vector iterators are random-access iterators, which are a
> superset of bidirectional iterators) but it would just copy the strings
> in reverse order, leaving each individual string unaffected.


yes, I knew that and that is why I did not even try to write that one.


> I'd carry out the operation in three steps: read in the strings, then
> reverse them, then write them out. You've got the reading and writing
> done. The obvious way to reverse them (at least to me) would be a
> functor that produces a reversed copy of an individual string, and
> std::transform to apply that to the whole vector.


I have created a function that does that thing and it works :

/* a function to reverse the string */
void rev_str( std::string& in_str )
{
std::string out_str;
for( std::string::const_reverse_iterator iter = in_str.rbegin();
iter != in_str.rend(); ++iter)
{
out_str.push_back( *iter );
}

in_str = out_str;
}



then I added this for reversing each string:

std::transform( svec.begin(), svec.end(), svec.begin(), rev_str )


and it raised a new mysterious error. 3rd argument to std::transform is
again svec.begin(), as I just want to put the result back into the same
vector and 4th argument is the function. I have tested the function and it
reverses a single string without any problem at all.


~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra reverse-input.cpp
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/stl_algo.h:
In function ‘_OutputIterator std::transform(_InputIterator,
_InputIterator, _OutputIterator, _UnaryOperation) [with _InputIterator =
__gnu_cxx::__normal_iterator<std::basic_string<cha r,
std::char_traits<char>, std::allocator<char> >*,
std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >, _OutputIterator =
__gnu_cxx::__normal_iterator<std::basic_string<cha r,
std::char_traits<char>, std::allocator<char> >*,
std::vector<std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::allocator<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > > > >, _UnaryOperation =
void (*)(std::string&)]’: reverse-input.cpp:36: instantiated from here
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/stl_algo.h:936:
error: no match for ‘operator=’ in ‘__result.
__gnu_cxx::__normal_iterator<_Iterator, _Container>:perator* [with
_Iterator = std::basic_string<char, std::char_traits<char>,
std::allocator<char> >*, _Container = std::vector<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > > >]() =
__unary_op(((std::string&)((std::string*)__first.
__gnu_cxx::__normal_iterator<_Iterator, _Container>:perator* [with
_Iterator = std::basic_string<char, std::char_traits<char>,
std::allocator<char> >*, _Container = std::vector<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >,
std::allocator<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > > >]())))’
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.h:490:
note: candidates are: std::basic_string<_CharT, _Traits, _Alloc>&
std::basic_string<_CharT, _Traits, _Alloc>:perator=(const
std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits
= std::char_traits<char>, _Alloc = std::allocator<char>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.h:498:
note: std::basic_string<_CharT, _Traits, _Alloc>&
std::basic_string<_CharT, _Traits, _Alloc>:perator=(const _CharT*) [with
_CharT = char, _Traits = std::char_traits<char>, _Alloc =
std::allocator<char>]
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.2.1/../../../../include/c++/4.2.1/bits/basic_string.h:509:
note: std::basic_string<_CharT, _Traits, _Alloc>&
std::basic_string<_CharT, _Traits, _Alloc>:perator=(_CharT) [with _CharT
= char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
~/programming/c++ $



-- arnuld
http://lispmachine.wordpress.com

 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      10-05-2007
> On Fri, 05 Oct 2007 21:19:58 +0500, arnuld wrote:

> I have created a function that does that thing and it works :
>
> /* a function to reverse the string */
> void rev_str( std::string& in_str )
> {
> std::string out_str;
> for( std::string::const_reverse_iterator iter = in_str.rbegin();
> iter != in_str.rend(); ++iter)
> {
> out_str.push_back( *iter );
> }
>
> in_str = out_str;
> }


OOPS!, I overlooked these words of Stroustrup (page-532, section 18.6.2):

"I didn't really want to produce a return value from move_shape().
However, transform() insists on assigning the result of its operation."


Hence I corrected my function and the whole program work fine now. any
advice on improving the code ?

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>

/* a function to reverse the string */
std::string rev_str( std::string& in_str )
{
std::string out_str;
for( std::string::const_reverse_iterator iter = in_str.rbegin(); iter != in_str.rend(); ++iter)
{
out_str.push_back( *iter );
}

return in_str = out_str;
}


int main()
{
std::vector<std::string> svec;

/* asks user for input & copied that into a vector of strings */
std::copy( std::istream_iterator<std::string>( std::cin ),
std::istream_iterator<std::string>(),
std::back_inserter( svec ) );

/* reverses each string (which is actually each element of the vector) */
std::transform( svec.begin(), svec.end(), svec.begin(), rev_str );

/* prints to std. out. */
std::cout << "\n------------------------------------\n";
std::copy( svec.begin(), svec.end(),
std:stream_iterator<std::string>( std::cout, "\n" ) );

return 0;
}

=========== OUTPUT ============
~/programming/c++ $ g++ -ansi -pedantic -Wall -Wextra reverse-input.cpp
~/programming/c++ $ ./a.out
amit
arnuld
sardar

------------------------------------
tima
dlunra
radras
~/programming/c++ $





-- arnuld
http://lispmachine.wordpress.com

 
Reply With Quote
 
Barry
Guest
Posts: n/a
 
      10-05-2007
arnuld wrote:
>> On Fri, 05 Oct 2007 07:49:47 -0600, Jerry Coffin wrote:

>
>> The two iterators specifying the input to reverse_copy are required to
>> be bidirectional iterators, and an istream_iterator isn't a
>> bidirectional iterator. In C++ 0x, when we get concepts, it'll be
>> possible to encode requirements like this directly, to allow a much more
>> informative error message (interestingly, as I understand things, this
>> problem with error messages was one of the original motivations for the
>> work that resulted in the concepts proposal).

>
> got that
>
>
>> In any case, it wouldn't really do any good if it did work. You could
>> (for example) use reverse_copy in place of the _second_ copy quite
>> easily (vector iterators are random-access iterators, which are a
>> superset of bidirectional iterators) but it would just copy the strings
>> in reverse order, leaving each individual string unaffected.

>
> yes, I knew that and that is why I did not even try to write that one.
>
>
>> I'd carry out the operation in three steps: read in the strings, then
>> reverse them, then write them out. You've got the reading and writing
>> done. The obvious way to reverse them (at least to me) would be a
>> functor that produces a reversed copy of an individual string, and
>> std::transform to apply that to the whole vector.

>
> I have created a function that does that thing and it works :
>
> /* a function to reverse the string */
> void rev_str( std::string& in_str )


string& rev_str

> {
> std::string out_str;
> for( std::string::const_reverse_iterator iter = in_str.rbegin();
> iter != in_str.rend(); ++iter)
> {
> out_str.push_back( *iter );
> }
>
> in_str = out_str;


std::reverse(in_str.begin(), in_str,end()); // do all the work

return in_str;
> }
>
>
>
> then I added this for reversing each string:
>
> std::transform( svec.begin(), svec.end(), svec.begin(), rev_str )


put the return of rev_str to
svec

actually, transform here is not a good idea, as it do call operator=,
though it do check on "this != &rhs".

you can simply write:

for (std::vector<std::string>::iterator iter = svec.begin();
iter != svec.end(); ++iter)
{
std::reverse(iter->begin(), iter->end());
}

>
>
> and it raised a new mysterious error. 3rd argument to std::transform is
> again svec.begin(), as I just want to put the result back into the same
> vector and 4th argument is the function. I have tested the function and it
> reverses a single string without any problem at all.
>
>


> -- arnuld
> http://lispmachine.wordpress.com
>

 
Reply With Quote
 
arnuld
Guest
Posts: n/a
 
      10-05-2007
> On Sat, 06 Oct 2007 00:50:46 +0800, Barry wrote:

> actually, transform here is not a good idea, as it do call operator=,
> though it do check on "this != &rhs".
>
> you can simply write:
>
> for (std::vector<std::string>::iterator iter = svec.begin();
> iter != svec.end(); ++iter)
> {
> std::reverse(iter->begin(), iter->end());
> }



your idea looks fine:


void rev_svec( std::vector<std::string>& svec)
{
for(std::vector<std::string>::iterator iter = svec.begin();
iter != svec.end(); ++iter )
{
std::reverse( iter->begin(), iter->end() );
}

}


but then I have to call the function independently, in main(), like this:

rev_svec( svec );


In my view, the std::transform looks clearer and reflects that we are
actually modifying the vector of strings but I am a newbie, So poke me
in the eye, if I am wrong.




-- arnuld
http://lispmachine.wordpress.com

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
reverse string, how to print string and not decimals? ssecorp C Programming 47 08-08-2008 06:48 PM
Accidental Reverse order String display Roedy Green Java 9 08-11-2005 01:30 PM
String Reverse Question Rakesh C Programming 45 04-20-2004 02:06 AM
Re: Reverse function of Server.MapPath(string file)? Curt_C [MVP] ASP .Net 0 01-22-2004 05:36 PM
Stacks Queues Reverse Reverse Polish dogbite C++ 4 10-10-2003 05:06 AM



Advertisments