1

Printing an integer each digit at a time in english form recursively

How to get the digits of a number without converting it to a string/ char array?

This is for coding in C, not C++. My knowledge of C is very limited, because I'm in the entry level course, and we just got past midterm. Try to keep this as simple as possible, because I can't include keywords or operators that we haven't covered in class. I don't think this is necessary, since I think it's just my logic that needs help, not my code.

Having referenced the above two examples to write my code for a class, I am stumped as how to finish up my last little piece of the puzzle. I have found a couple of questions-answers here on SO that appeared to be relevant, however they used code to solve the problem that I have no knowledge on. Hopefully, someone can help me with my logic here.

My goal of my assignment is to:

Take a user defined integer, and display the digits in english. For example:

Please enter an integer: 123
You have entered: One Two Three

Then, I need to add up the sum of the digits (and if digits<10, display in english). In this case:

The sum of the individual digits is: Six

Finally, I need to then average the digits using 2 decimal places. In this case:

The average is: 2.00

I have ALL of this completed. Except: My first step lists the digits backwards! It reads 10s place, 100s place, 1000s place, etc. For example:

Please enter an integer: 123
You have entered: Three Two One

My conditions for this portion of the assignment, is that I may use only one switch statement, and I have to use a switch statement (meaning the need for a loop (I went with do)). I may also not use arrays. But finally, and most importantly, I may NOT reverse the input number (which was the solution to the the first version of this assignment). If I could do that, I would not be here.

Here is the excerpt of code that is relevant.

#include <stdio.h>

int main(void)

{

    int userinput, digit

    printf("Please input a number:");
    scanf("%d", &userinput);

    printf("You have entered: ");

    if (userinput < 0)
    {
            printf("Negative ");
            userinput = -userinput;
    }

    do
    {
            digit = userinput%10;
            switch (digit)
            {
                    case 0:
                    {
                            printf("Zero ");
                            break;
                    }
                    case 1:
                    {
                            printf("One ");
                            break;
                    }
                    case 2:
                    {
                            printf("Two ");
                            break;
                    }
                    case 3:
                    {
                            printf("Three ");
                            break;
                    }
                    case 4:
                    {
                            printf("Four ");
                            break;
                    }
                    case 5:
                    {
                            printf("Five ");
                            break;
                    }
                    case 6:
                    {
                            printf("Six ");
                            break;
                    }
                    case 7:
                    {
                            printf("Seven ");
                            break;
                    }
                    case 8:
                    {
                            printf("Eight ");
                            break;
                    }
                    case 9:
                    {
                            printf("Nine ");
                            break;
                    }
                    default:
                    {
                            break;
                    }

            }

            userinput = userinput/10;

    } while (userinput > 0);

    printf("\n");
Community
  • 1
  • 1
Hamberglar
  • 9
  • 1
  • 5

3 Answers3

1

If you can't use an array, use recursion:

void print_textual(int n)
{
    if (n > 9) {
        print_textual(n / 10);
    }

    switch (n % 10) {
    case 0: printf("zero "); break;
    case 1: printf("one "); break;
    case 2: printf("two "); break;
    case 3: printf("three "); break;
    case 4: printf("four "); break;
    case 5: printf("five "); break;
    case 6: printf("six "); break;
    case 7: printf("seven "); break;
    case 8: printf("eight "); break;
    case 9: printf("nine "); break;
    }
}

By the way, this would really be much better if you could use an array for at least the digit names:

void print_textual(int n)
{
    if (n > 9) {
        print_textual(n / 10);
    }

    static const char *names[] = {
        "zero",
        "one",
        "two",
        "three",
        "four",
        "five",
        "six",
        "seven",
        "eight",
        "nine"
    };

    printf("%s ", names[n % 10]);
}
  • Might print unexpected strings if n < 0? – chux - Reinstate Monica Nov 09 '13 at 18:59
  • @chux I don't believe that's legal input based on the example OP provided. –  Nov 09 '13 at 19:08
  • I'm not sure how this works, so could someone explain it? Also, yes. I need < 0 input to be usable. As you can see by the first if statement, I even check for that so I can print "Negative " and change the integer to a positive number. – Hamberglar Nov 09 '13 at 19:19
  • @Hamberglar Then you can leave that part in your code and it will work for negative numbers as well. It works like this: if you used modulo arithmetic and division in a loop, that would print the numbers in reverse order (starting with the LSD to the MSD). Now if you instead recurse **before** actually printing the digit, it will reverse the order in which they are printed, so you get back the original order. –  Nov 09 '13 at 19:24
  • I had this problem with the comments on my question, too. I don't actually know what recursion is... Edit: To clarify, this means I can't use recurse either. – Hamberglar Nov 09 '13 at 19:25
  • @Hamberglar If you can't use neither recursion, nor an array, then you can't solve this problem. –  Nov 09 '13 at 19:27
  • Considering this is an assignment given to me for a class, I don't believe that's possible. There must be a way. – Hamberglar Nov 09 '13 at 19:31
  • @Hamberglar I suspect that the rest of your class knows what either of an array or recursion is... –  Nov 09 '13 at 19:33
  • To clarify, the only requirement for how I complete the assignment is to use a switch statement and only one switch statement, and not to use arrays or anything we haven't covered in class. It doesn't necessarily need to use the logic I used. That's just the only way I could think of to get something worthwhile to print. – Hamberglar Nov 09 '13 at 19:33
  • I actually do know what arrays are, but it was specified that we can't use them, because we learned them after this assignment was given. If there's a way to use recursion without the recurse keyword, then that's what needs to be done, but I don't know how to do that since we haven't covered recursion. – Hamberglar Nov 09 '13 at 19:34
  • @Hamberglar You could as well use an infinitely long `switch` statement, enumerating all possible integers. And then you used only a switch statement. But I'm pretty confident that's not a requirement. –  Nov 09 '13 at 19:34
  • @Hamberglar What "recurse keyword"? –  Nov 09 '13 at 19:35
  • I have no idea how to use recursion, so I assumed when you said "recurse" that meant a keyword. When I looked up recursion, that seemed to be confirmed because they used recurse as a keyword. – Hamberglar Nov 09 '13 at 19:37
  • @Hamberglar No. Recursion means that a function calls itself. There's no such keyword in C, nor is it necessary. –  Nov 09 '13 at 19:38
  • Then I'm going to look up recursion and see if it fits within the parameters of my knowledge. Thank you for the help and sorry for misunderstanding! – Hamberglar Nov 09 '13 at 19:39
0

To avoid using recursion, form a power-of-10 multiplier scaled to n. Then use this multiplier to determine the digits in most significant to least significant order.

Use the same digits_in_english() to print the digit sum.

void digits_in_english(const char *prompt, int n, int *Sum, int *Count) {
  fputs(prompt, stdout);
  *Sum = 0;
  *Count = 0;
  if (n < 0) {
    printf(" Negative");
    n = -n;
  }
  int m = n;
  int pow10 = 1;
  while (m > 9) {
    m /= 10;
    pow10 *= 10;
  }
  do {
    static const char *Edigit[] = { "Zero", "One", "Two", "Three", "Four",
       "Five", "Six", "Seven", "Eight", "Nine" };
    int digit = n / pow10;
    *Sum += digit;
    (*Count)++;

    // OP knows how to put a switch statement here instead of printf()
    printf(" %s", Edigit[digit]);

    n -= digit * pow10;
    pow10 /= 10;
  } while (pow10 > 0);
  fputs("\n", stdout);
}

void Etest(int n) {
  int Count, Sum;

  // Change this to a printf() and scanf()
  printf("Please enter an integer: %d\n", n);

  digits_in_english("You have entered:", n, &Sum, &Count);
  double Average = (double) Sum / Count;

  // Do no care about the resultant Sum, Count
  digits_in_english("The sum of the individual digits is:", Sum, &Sum, &Count);

  printf("The average is: %.2f\n\n", Average);
}

sample

Please enter an integer: -2147483647
You have entered: Negative Two One Four Seven Four Eight Three Six Four Seven
The sum of the individual digits is: Four Six
The average is: 4.60

Does not work for INT_MIN. A bit tricky to do so in a portable way.

It appears OP is not allowed to use arrays. Hope that does not include strings.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
-2

So, through a lot of stumbling around, I managed to make my code work the way it was intended using only the knowledge I was allowed to use. Here's the finished product (unless someone sees any huge errors):

    //initializing variables, of course
    int userinput, number1, number2, numbersum;
    int div = 1;
    float number3;

    //displaying instructions to the user
    printf("Please input a number: ");
    scanf("%d", &userinput);

    printf("You have entered: ");

    if (userinput < 0)
    {
            printf("Negative ");
            userinput = -userinput;
    }

    //the variables number1-3 are for the data analysis at the end
    //I am preserving the original input in them so I can mutilate it in the following step
    number1 = userinput;
    number2 = userinput;

    while (div <= userinput)
    {
            div = div*10;
    }

    do
    {
            if (userinput != 0)
            {
                    div = div/10;

                    switch (userinput/div)
                    {
                            case 0:
                            {
                                    printf("Zero ");
                                    break;
                            }
                            case 1:
                            {
                                    printf("One ");
                                    break;
                            }
                            case 2:
                            {
                                    printf("Two ");
                                    break;
                            }
                            case 3:
                            {
                                    printf("Three ");
                                    break;
                            }
                            case 4:
                            {
                                    printf("Four ");
                                    break;
                            }
                            case 5:
                            {
                                    printf("Five ");
                                    break;
                            }
                            case 6:
                            {
                                    printf("Six ");
                                    break;
                            }
                            case 7:
                            {
                                    printf("Seven ");
                                    break;
                            }
                            case 8:
                            {
                                    printf("Eight ");
                                    break;
                            }
                            case 9:
                            {
                                    printf("Nine ");
                                    break;
                            }
                            default:
                            {
                                    break;
                            }

                    }

                    userinput = userinput%div;

            }

            else
            {
                    printf("Zero");
            }

    } while (userinput > 0);

    //line break to make it look pretty
    printf("\n");

    //boring math to determine the sum of the digits
    //assuming all are positive due to know contrary instructions
    //set equal to zero since this variable refers to itself in the following function
    numbersum = 0;

    while (number1 > 0)
    {
            numbersum = numbersum + (number1 % 10);
            number1 = number1 / 10;
    }

    //nested switch in if statement to print english if digits less than or equal to 10
    if (numbersum <= 10)
    {
            switch (numbersum)
            {
                    case 0:
                    {
                            printf("The sum of the individual integers is: Zero");
                            break;
                    }
                    case 1:
                    {
                            printf("The sum of the individual integers is: One");
                            break;
                    }
                    case 2:
                    {
                            printf("The sum of the individual integers is: Two");
                            break;
                    }
                    case 3:
                    {
                            printf("The sum of the individual integers is: Three");
                            break;
                    }
                    case 4:
                    {
                            printf("The sum of the individual integers is: Four");
                                    break;
                    }
                    case 5:
                            {
                            printf("The sum of the individual integers is: Five");
                            break;
                    }
                    case 6:
                    {
                            printf("The sum of the individual integers is: Six");
                            break;
                    }
                    case 7:
                    {
                            printf("The sum of the individual integers is: Seven");
                            break;
                    }
                    case 8:
                    {
                            printf("The sum of the individual integers is: Eight");
                            break;
                    }
                    case 9:
                    {
                            printf("The sum of the individual integers is: Nine");
                            break;
                    }
                    case 10:
                    {
                            printf("The sum of the individual integers is: Ten");
                    }
                    default:
                    {
                            break;
                    }

            }

            printf("\n");
    }

    //else if greater than 10, just print the decimal number
    else
    {
            printf("The sum of the individual digits in the integer is: %d\n", numbersum);
    }

    if (numbersum == 0)
    {
            printf("The average is of zero is not a number.\n");
    }

    else
    {

            //initializing a variable here because it's totally irrelevant to the above functions
            //and this feels cleaner because of it. I'm not sure if this is bad etiquette
            int i;

            //picks out the number of digits in the input and effectively sets i to that number
            for (i = 0; number2 > 0; i++)
            {
                    number2 = number2/10;
            }

            //this is necessary for turning number3 into an actual floating point, not an int stored as float
            number3 = numbersum;

            //math to determine average (sum of digits divided by number of digits)
            number3 = number3 / i;

            printf("The average is: %.2f\n", number3);

    }

    return 0;

It's big and it's probably kind of sloppy (due to how new I am), but it works and that's all that really matters to me right now.

Thanks for the help, guys.

Hamberglar
  • 9
  • 1
  • 5
  • 1) "if greater than 10, just print the decimal number" is taking the easy way out. Just loop like the previous major loop. 2) `numbersum == 0` is not needed. "0" should be a valid entry as the average digits is 0. 3) _Somehow_ the 2 tasks that need an integer to textual output should use the same code (a function). Replicating code (the 2 big switch statements) is a coding technique of _last_ resort. 4) Programming tasks "do this without using a feature of the language" are value limited. I've had to code without access to typical _functions_, but not w/o core language feature like _arrays_. – chux - Reinstate Monica Nov 14 '13 at 15:21
  • Actually, it was specified in the instructions that I can take the "easy way out" so I jumped on that. I think you might be right about the 0 part. I think i was overthinking that (thought a div/0 thing might be possible). – Hamberglar Nov 14 '13 at 21:30
  • Right that `i=0` and `number3 / i` is a non-no. It can be avoided with `i=0; do { i++; number2 = number2/10; } while (number2 > 0)`. Remember this idiom to allow 0 to loop once, but still be a terminating condition. I used the `do { ...} while (pow10 > 0)` in my answer for the same reason, as you did in your `do { } while (userinput > 0)`. – chux - Reinstate Monica Nov 14 '13 at 23:56