Hi everyone,
I'm having trouble with this program, I hope you can help me with it. I have to write a function that takes an integer value and returns the number with its digits reversed. This is what I have so far...... I will put a */* where i need your help.....

#include<iostream>

using std::cout;
using std::cin;
using std::endl;

#include<iomanip>

using std::setw;

[U]/* write prototype for reverseDigits */[/U]
[U]/* write prototype for width */[/U]

int main()
{
   int number;

   cout << "Enter a number between 1 and 9999: "'
   cin >> number;
   cout << "The number with its digits reversed is: "
          << setw ( [U]/* write call for width */ [/U] )
          << [U]/* write call for reverseDigits */[/U]
          << endl;

 return 0;
}

[U] /* write function header for reverseDigits */[/U]
{
  int reverse = 0;
  int divisor = 1000;
  int multiplier = 1;

  while ( n > 10 ) {

      if ( n >= divisor ) {
         reverse += n / divisor * multiplier;
         n %= divisor;
         [U]/* write a line of code that reduced divisor by a factor of 10 */
         /* write a line of code that increased multiplier by a factor of 10 */[/U]

          }
          else
              divisor /= 10;
        }
        reverse += n * multiplier;
        return reverse;

   }

   [U]/* write function header for width */[/U]
  {
        if ( n / 1000 )
           return 4;
        else if ( n / 100 )
           return 3;
        else if ( n/10)
           return 2;
        else
           return 1;
}

<< moderator edit: added [code][/code] tags >>

Surely you can take a stab at the "write a prototype" part. You have been dumping homework and not showing an attempt to solve them yourself. Please read the Announcement.

why would you need to use width for this question??
couldnt you just reverse them without it? or is it needed?

>couldnt you just reverse them without it? or is it needed?
It looks like width is strictly for pretty formatting. Rather than assume the largest possible number of digits and suffer extra leading spaces, width is used to ensure that only a single space precedes the reversed number regardless of how many digits it has.

#include<iostream.h>
#include<conio.h>
main()
{
// declare variables
int number, digit;
// prompt the user for input
cout <<"Please enter 4-digit number:";
cin>>number;
//get the first digit and display it on screen
digit = number % 10;
cout <<"The digits are;";
cout <<digit <<",";
//get the remaining three digits number=number/10;
//get the next digit and display it
number=number/10;
digit=number % 10;
cout<<digit<<",";
// get the remaining two digits number
number=number/10;
// get the next digit and display it
digit=number%10;
cout<<digit<<",";
//get the remaining one digit number
number=number /10;
//get the next digit and display it 
digit = number % 10;
cout<<digit;
getch();
}

<< moderator edit: added [code][/code] tags >>

In the more general case, you could look at this problem as popping one stack and pushing another stack. (The stacks containing decimal digits.):

#include <string>
std::string rev_digits(unsigned long n) {
    std::string ret;
    while (n) {
        ret.push_back('0' + (n % 10));
        n /= 10;
    }
    return ret;
}

or if you want to return an integer with reversed digits:

/* If n is 10 digits and its units last digit is 4
or greater, there may be problems. (i.e. if the reversed
form is greater than the 32nd power of 2) */
unsigned long rev_digits(unsigned long n) {
    unsigned long ret = 0;
    while (n) {
        ret *= 10;
        ret += n % 10;
        n /= 10;
    }
    return ret;
}
#include <sstream>
#include <string>
using namespace std;

unsigned long reverse_digits(unsigned long in)
{
    //we convert the argument to a string and then reverse it
    ostringstream oss1, oss2;
    oss<<in;
    string::reverse_iterator r_it=oss1.str().rbegin();
    while(r_it != oss1.str().rend())oss2<<*r_it;
    //we convert the reversed string into an unsigned long
    return atol(oss2.str().c_str()); //atol is defined in stdlib.h
}

Edited 3 Years Ago by happygeek: fixed formatting

Dieter your code can't be compiled by me so I use:

std::stringstream my_stringstream;
	my_stringstream <<  in;
	string msg = my_stringstream.str();	
	string msg2= my_stringstream.str();	//something to hold the reversed string
	int len=0;
	string::reverse_iterator rit=msg.rbegin();
	while (rit<msg.rend()){
		msg2[len]=*rit;
		++rit; //move one position backwards
		++len;
	}	
	return atol(msg2.c_str());

Sorrry !!

My code did not compile because it doesn't work ! :sad:

In fact I often post code that doesn't compile (I know it is bad, but when I read a problem, I often have the solution in mind, so I write the code directly)

Here is a corrected working (and tested) version.

It compiles well using dev-cpp 4.9.9.2

unsigned long reverse_digits(unsigned long in)
{
    //we convert the argument to a string and then reverse it
    ostringstream oss1, oss2;
    oss1<<in;//<---changed this line
    string::reverse_iterator r_it=oss1.str().rbegin();
    while(r_it != oss1.str().rend())oss2<<*(r_it++);//<- and this one because i forgot to increment the iterator
    //we convert the reversed string into an unsigned long
    return atol(oss2.str().c_str()); //atol is defined in stdlib.h
}

Your solution is quite good, too.

What kind of compiler do you use ? (I'm surprised that you can't include sstream)

I use gcc version 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)
still i got segmentation error by running your code, never used oss before so I am wondering it might
be the incrementation is over limit.

>Here is a corrected working (and tested) version.
It's still wrong. Keep in mind that oss1.str() will create a whole new string object each time you call it. Now, how much sense does it make to start your iterator in one string object and expect it to intelligently traverse over multiple string objects? This will compile and run:

unsigned long reverse_digits ( unsigned long in )
{
  ostringstream oss1, oss2;

  oss1<< in;

  string save = oss1.str();
  string::reverse_iterator r_it = save.rbegin();

  while ( r_it != save.rend() )
    oss2<< *r_it++;

  return atol ( oss2.str().c_str() );
}

sorry to insiste, but both solutions work on my computer.
(even if I know that your solution is faster)

Here is the code I used to test it :

#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <string>
using namespace std;

#include <limits.h>

unsigned long reverse_digits_dieter_version(unsigned long in)
{
    //we convert the argument to a string and then reverse it
    ostringstream oss1, oss2;
    oss1<<in;
    string::reverse_iterator r_it=oss1.str().rbegin();
    while(r_it != oss1.str().rend())oss2<<*(r_it++);
    //we convert the reversed string into an unsigned long
    return atol(oss2.str().c_str()); //atol is defined in stdlib.h
}

unsigned long reverse_digits_narue_version( unsigned long in )
{
  ostringstream oss1, oss2;

  oss1<< in;

  string save = oss1.str();
  string::reverse_iterator r_it = save.rbegin();

  while ( r_it != save.rend() )
    oss2<< *r_it++;

  return atol ( oss2.str().c_str() );
}

//#define TEST_LENGTH ULONG_MAX
#define TEST_LENGTH 1000000

int main(void)
{
	int counter=0;
	cout<<"testing reverse_digits :"<<endl;
	for(unsigned long i=0; i<TEST_LENGTH;i++)
	{
		unsigned long l1=reverse_digits_dieter_version(i);
		unsigned long l2=reverse_digits_narue_version(i);
		if(l1!=l2)
		{
			cout<<"an error was detected ! ("<<l1<<"!="<<l2<<")"<<endl;
			break;
		}
		if(!(i%(TEST_LENGTH/10)))cout<<(counter++)*10<<"%"<<endl;
	}
	cout<<"... done"<<endl;

	cout<<"press [enter]"<<endl;
	getchar();
	return 0;
}

>sorry to insiste
As you should be.

>but both solutions work on my computer.
This is a classic excuse for doing something stupid, and nobody buys it. Just because it works for you doesn't mean it works for everyone else. How arrogant can you be to expect everyone else to use your exact system and compiler configuration to run your software? If it works for you, but one person tells you it crashes, the code is probably wrong. If two people tell you it crashes, the code is probably wrong. If one of those people has implemented the portion of the standard library in question, the code is definitely wrong because unless you have too, that person probably knows how things work better than you.

>(even if I know that your solution is faster)
It doesn't matter how fast a solution is if it's broken.

>Here is the code I used to test it :
Unless you've used more than one operating system and more than two compilers, all you've tested is the quirks of your implementation.

Don't be so agressive.


I don't know about your skills and you do not know about mine, so don't be so pretentious.

I tried to see what was wrong with my proposition, and i did not find. That's not a reason to treat me like you do.

Contrary to you, I write on these kind of forums in order to find new solutions and improve my own level by proposing solutions to others. My last post aimed at introducing the fact that I didn't know what was wrong with my code.

I have tested it since your last post :
Under Windows XP pro, using MinGW32 3.4, and VC7 (the free commandline version)
and under Mandrake Linux 10.1, using g++
EACH TIME IT WORKED.

So tell me what is wrong instead of insulting me like you do.

If one of those people has implemented the portion of the standard library in question,

PS : Don't insinuate you wrote a part of the standard library, as it make me laugh too much (which implementation ?). Even If you were Linus Thorvald, I wouldn't excuse your disgusting behavior.

>Don't be so agressive.
Don't be so defensive.

>I don't know about your skills and you do not know about mine, so don't be so pretentious.
I have a fairly good idea of your skills based on what you've posted so far, perhaps you should be less pretentious.

>Contrary to you
Indeed. I'm here to help people learn and improve, whilst you seem to only care about yourself when you "improve your level" by proposing obviously incorrect solutions.

>So tell me what is wrong instead of insulting me like you do.
I did tell you what was wrong. You didn't like it and insisted that your broken code was correct because it "works for you". Look, it doesn't take much brain power to realize what's wrong:

string::reverse_iterator r_it=oss1.str().rbegin();

This gives you an iterator to the result of oss1.str(). Keep in mind that stringstream::str() returns a basic_string<>, not a basic_string<>&.

while(r_it != oss1.str().rend())

r_it is an iterator into a temporary object, because you didn't save the string returned by oss1.str(). That alone is an issue, but then you compare it with an iterator to another temporary object. If you can't see the potential issues of trying to iterate from the beginning of one container to the end of another container, you really need to work on quality over quantity when it comes to programming.

>Don't insinuate you wrote a part of the standard library
Okay, I'll make it clear. I have written large portions of the standard C++ library. I have written most of the standard C library. Since you admitted to knowing nothing about me, why does this seem so far-fetched?

>which implementation ?
You think I release all of the code that I write?

>Even If you were Linus Thorvald, I wouldn't excuse your disgusting behavior.
That's your problem, not mine. If you were really here to become a better programmer then you would be thanking me for correcting you and then showing you how to fix your mistake, not arguing with me.

This article has been dead for over six months. Start a new discussion instead.