2

So I've been working my way through Kochan's Programming in C and I've hit a snag on one of the questions which reads as follows:

"Write a program that takes an integer keyed in from the terminal and extracts and displays each digit of the integer in English. So if the user types in 932, the program should display the following: nine three two (Remember to display zero if the user types in just 0.)"

I had managed to get the program to print out the digits as words but unfortunately in reverse order. From there I thought it might be a good idea to reverse the number so to speak, but now when I run that value through my program only prints out "one one one ...." for how ever many digits long the number I enter in.

In other words, originally I managed to display 932 as "two three nine", but when I tried to reverse the number and run 239 through my program I only get "one one one".

If any one has any hints that could point me in the right direction it would be very much appreciated! My code is below:

   #include <stdio.h>

int digitCount (int);
int reverseNumber (int);

int main(void)
{
    //Chapter 6 Problem 6
    int x, numberValue;

    printf("Enter the number you'd like converted to words\n");
    scanf("%i", &x);

    numberValue = reverseNumber(x);
    printf("The reverse is %i\n", numberValue);

    do {
        numberValue = numberValue % 10;

        switch (numberValue) {
            case 0:
                printf("zero\t");
                break;

            case 1:
                printf("one\t");
                break;

            case 2:
                printf("two\t");
                break;

            case 3:
                printf("three\t");
                break;

            case 4:
                printf("four\t");
                break;

            case 5:
                printf("five\t");
                break;

            case 6:
                printf("six\t");
                break;

            case 7:
                printf("seven\t");
                break;

            case 8:
                printf("eight\t");
                break;

            case 9:
                printf("nine\t");
                break;

            default:
                break;
        }

        x = x / 10;

    } while (x != 0);

    return 0;
}

int digitCount (int u)
{
    int cnt = 0;

    do {
        u = u / 10;
        cnt++;

    } while (u != 0);

    return cnt;
}

int reverseNumber (int y)
{
    int cnt, Rev;
    cnt = digitCount(y);  //returns number of digits

    while (cnt != 0) {
        Rev = Rev * 10 + y % 10;
        y = y / 10;
        cnt--;
    }

    return Rev;
}
ImpurestClub
  • 193
  • 1
  • 4
  • 15
  • Hey, sorry about that, I'll be sure to be more descriptive in the future. – ImpurestClub Oct 30 '13 at 13:54
  • possible duplicate of [how to get different digits starting from the most significant digit in a number in c?](http://stackoverflow.com/questions/16967008/how-to-get-different-digits-starting-from-the-most-significant-digit-in-a-number) – abelenky Oct 30 '13 at 15:23

3 Answers3

1

In your reverseNumber function you have not initialized Rev. Make Rev=0

int reverseNumber (int y)
{
    int cnt, Rev=0;
    cnt = digitCount(y);  //returns number of digits

    printf("Digit count %d\n", cnt);
    while (cnt != 0) {
        Rev = Rev * 10 + y % 10;
        y = y / 10;
        cnt--;
    }

    return Rev;
}

In main in the do while loop use a temporary variable since you are overwriting numberValue with numberValue % 10. But the most ironic part in your program (where you complicated everything for yourself) is that there is no need to reverse the number at all. See the code here

  1. In the way user entered - http://ideone.com/pORaP2
  2. In reverse order - http://ideone.com/5GS8al

When you find modulo you get the number in the reverse order itself. Suppose you entered 234

  1. First step 234%10 gives 4 prints four. And then makes 234 to 23

  2. Second step 23%10 gives 3 prints three. And then makes 23 to 2

and then finally prints two.

Sadique
  • 22,572
  • 7
  • 65
  • 91
  • Thank you! I was actually trying to **stop** it from printing in reverse order though, which is why I reversed the number beforehand (and made things more complicated). – ImpurestClub Oct 30 '13 at 14:12
  • Hey! Unfortunately it still suffers from the same issues I mentioned earlier. I want it to print the answer in the order the user entered it in--not the reverse. But when I reverse the number and then run it through the `do while` loop I only get "one .... one" as my result. – ImpurestClub Oct 30 '13 at 14:22
  • @user2936520 See my edits in the program. I have edited my answer and shown result both ways. – Sadique Oct 30 '13 at 14:25
  • Thank you so much for your help! Worked perfectly. – ImpurestClub Oct 30 '13 at 14:49
0

Consider what the primary problem is you are dealing with, you need to process the left most digit first, then the next to the right, then the next. But the math of using modulus and division goes from right to left. So what you need is some way to either save the math processing and reverse, or have the output be delayed. Two options are available.

For an iterative approach you could utilize a FIFO queue type approach that holds the results of each digit and then prints out the queue. Could be as simple as an array with indexing:

int main(void) {
  int x, i;
  int result[32];     //arbitrary size
  int index = 0;

  printf("Enter the number you'd like converted to words\n");
  scanf("%i", &x);

 do {
    results[index++] = x % 10;
    x = x / 10;
  } while( index < 32 && x != 0 );

  //now print in reverse order
  for(i = index-1; i >= 0; i--) {
     switch (results[i]) {
       case 0:
         printf("zero\t");
         break;

       case 1:
         printf("one\t");
         break;  

       case 2:
         printf("two\t");
         break;

       case 3:
         printf("three\t");
         break;

       case 4:
         printf("four\t");
         break;

       case 5:
         printf("five\t");
         break;

       case 6:
         printf("six\t");
         break;

       case 7:
         printf("seven\t");
         break;

       case 8:
         printf("eight\t");
         break;

       case 9:
         printf("nine\t");
         break;

       default:
          break;
    }       
  }
}

There is second approach that works which is recursive. Here you delay the printing of the output until you reach the left most digit. The built in stack is used for by the recursive calls.

void printNumbers(int x);

int main(void) {
   int x;

   printf("Enter the number you'd like converted to words\n");
   scanf("%i", &x);
   printNumbers(x);
}

void printNumbers(int v) {
    if( v > 9 ) {
        printNumbers( v / 10 );
    }
    switch (v%10) {
      case 0:
        printf("zero\t");
        break;

      case 1:
        printf("one\t");
        break;

      case 2:
        printf("two\t");
        break;

      case 3:
        printf("three\t");
        break;

      case 4:
        printf("four\t");
        break;

      case 5:
        printf("five\t");
        break;

      case 6:
        printf("six\t");
        break;

      case 7:
        printf("seven\t");
        break;

      case 8:
        printf("eight\t");
        break;

      case 9:
        printf("nine\t");
        break;

      default:
        break;
    }
 }

Both approaches will solve the problem, but not if the input is a negative number.

Jere
  • 581
  • 2
  • 3
0

My simple answer:

void printNum(int x)
{
    static const char * const num[] = {
        "zero ", "one ", "two "  , "three ", "four ",
        "five ", "six ", "seven ", "eight ", "nine "
    };

    if (x < 10) {
        printf(num[x]);
        return;
    }
    printNum(x / 10);
    printNum(x % 10);
}
abelenky
  • 63,815
  • 23
  • 109
  • 159