C - Попытка преобразовать неопределенное количество введенных цифр в соответствующие отдельные слова

Я знаю, что это чем-то похоже на программу, которая преобразует цифры в слова, используя такие вещи, как «Тысячи», «Сотни» и т. д. Однако я хочу взять целое число любого размера (например, 543210) и создать вывод «Пять четыре три два один ноль». Я использую оператор switch, который, я думаю, я полностью понимаю и работаю. Я застрял в использовании какого-то цикла, чтобы выделить каждую цифру целого числа и напечатать его слово, а затем повторить для следующей цифры и следующей. Я довольно новичок во всем этом, поэтому любая помощь будет оценена по достоинству! Спасибо.

Вот что у меня есть до сих пор (немного, но я застрял на том, куда идти с циклом):

#include <stdio.h>

int main(void)
{
        int num;

        printf("Please enter an integer: \n");
        scanf("%d", & num);

        while (num==0)
        {
        switch (num)
        {
                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 ");
                case (8):
                        printf("Eight ");
                        break;
                case (9):
                        printf("Nine ");
                        break;
                case (10):
                        printf("Ten ");
                        break;

        }
        }
        return 0;

}

person Sara Tine    schedule 06.11.2013    source источник
comment
попробуйте прочитать строку с помощью fgets и выполнить цикл, пока не увидите завершающий нуль.   -  person Hayri Uğur Koltuk    schedule 07.11.2013


Ответы (5)


Самый простой способ сделать это - использовать цифры с правой стороны, используя целочисленное деление «/» и «%».

Вот некоторый частичный код:

int digit;
//start a loop
//if num > 10
digit = num % 10;
num = num / 10;
//else
digit = num;
//break the loop

Это напечатает числа справа налево. Если вы хотите слева направо, вы можете создать рекурсивную функцию, которая, если num > 10, вызывает себя с параметром num/10, а затем печатает цифровое значение.

Изменить: вот пример вашей рекурсивной функции:

void convertToWords (int num){
    if (num > 10){
        convertToWords(num / 10);
    int digit = num % 10;
    //your switch statement to print the words goes here
}
person NL - Apologize to Monica    schedule 06.11.2013
comment
Спасибо за комментарий, к сожалению, я новичок в c, и такие вещи, как рекурсивные функции и использование циклов для стека значений, мне совершенно чужды. - person Sara Tine; 07.11.2013
comment
вы бы поместили цифру в оператор switch вместо num. - person NL - Apologize to Monica; 07.11.2013

поэтому вы можете попробовать прочитать строку с помощью fgets и выполнить цикл до конца строки (или, как в моем примере кода, до конца цифр) и вывести имена цифр.

#include <stdio.h>

char *names[10] = {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", };
int main()
{
    char buffer[500] = {0};
    int i = 0;
    fgets(buffer, sizeof(buffer), stdin);
    while (isdigit(buffer[i]))
        printf("%s ", names[buffer[i++] - '0']);

    return 0;
}

http://ideone.com/Ba7Rs3

person Hayri Uğur Koltuk    schedule 06.11.2013

Самый понятный способ ИМО (если не самый эффективный) использует степени десяти. Если мы начнем с числа 543210, то количество цифр будет равно log10(543210) + 1 = 6. Тогда

// start with a number
int num = 543210;
// how many digits?
int digits = log10(num) + 1; // 6
// now loop through each digit
for (int i = digits - 1; i > 0; --i) {
  int p = (int)pow(10, i);
  int digit = (num / p) % 10; // we want integer division
  switch (digit) { ... }
}

(Не забудьте #include <math.h>.)

person michaelb958--GoFundMonica    schedule 06.11.2013

Один из возможных подходов:

#include <stdio.h>

char *digits[10] = {
  "Zero", "One", "Two", "Three", "Four",
  "Five", "Six", "Seven", "Eight", "Nine"
};

int main() {
  int num, digit; 
  long long tenth = 1;
  printf("Please enter an integer: \n");
  scanf("%d", &num);

  while (tenth < num) {
    tenth *= 10;
  }

  while (tenth > 1) {
    tenth /= 10;
    digit = num / tenth;
    num %= tenth;
    printf("%s ", digits[digit]);
  }
  return 0;
}

Демо. Теперь пояснения:

Прежде всего, нет особого смысла использовать здесь switch: цифры чертовски линейны по своей природе, поэтому их имена могут (и должны) вместо этого храниться в массиве строк (char *digits[10] в этом коде). Затем вы сможете получить метку для определенной цифры, просто обратившись к этому массиву, используя эту цифру в качестве индекса.

Во-вторых, ключевой проблемой этой программы является извлечение каждой цифры из ввода отдельно. Проще делать справа налево (брать результат number % 10, присваивать number / 10 number, повторять), но здесь надо действовать по-другому - слева направо. Итак, что мы делаем:

  • вычислить tenth - первую степень 10, которая больше заданного числа (например, если мы работаем с 546, это будет 1000)
  • на каждой последующей итерации:

-- разделить tenth на 10

-- обработать результат целочисленного деления number на tenth

-- присвоить обратно number остаток от number, разделенного на tenth

На первой итерации tenth становится 100 (1000/10), 546/100 дает вам 5 (целое число, деленное на целое число, является целым числом, десятичные дроби усекаются), 546 % 100 дает вам 46 - это сохраняется как число для второй итерации.

На второй итерации tenth становится 10 (100/10), 46/10 дает вам 4, 46 % 10 дает вам 6. Следующий цикл: 10/10 => 1, 6/1 => 6, 6%1 => 0 Итак, tenth стало равным 1, и цикл остановлен - так как все цифры обработаны.

person raina77ow    schedule 06.11.2013

Безлимитное решение, вдохновленное @Hayri Uğur Koltuk

#include <ctype.h>
#include <stdio.h>
int main() {
  int ch;
  while (((ch = getc(stdin)) != EOF) && (isdigit(ch))) {
    static const char *Digit[10] = { "Zero", "One", "Two", "Three", "Four",
        "Five", "Six", "Seven", "Eight", "Nine" };
    printf("%s ", Digit[ch - '0']);
  }
  puts("\n");
  return 0;
}

Простое рекурсивное решение

static void PrintDigit(unsigned n) {
  static const char *Digits[10] = {
    "Zero", "One", "Two", "Three", "Four",
    "Five", "Six", "Seven", "Eight", "Nine" };
  if (n > 9) {
    PrintDigit(n/10);
  }
  printf("%s ", Digits[n%10]);
}

void PrintDigits(unsigned n) {
  PrintDigit(n);
  printf("\n");
}
person chux - Reinstate Monica    schedule 07.11.2013
comment
Цикл while действительно упрощается до while ( isdigit(ch = getc(stdin)) ) {, но некоторые считают передачу потенциального EOF is() плохим стилем, хотя согласно спецификации это допустимо. - person chux - Reinstate Monica; 07.11.2013