【问题标题】:C - Trying to convert an unspecified amount of digits entered into their respective individual wordsC - 尝试将输入的未指定数量的数字转换为各自的单词
【发布时间】:2013-11-06 21:59:28
【问题描述】:

我知道这有点类似于使用“千”、“百”等将数字转换为单词的程序。但是,我希望采用任意大小的整数(例如 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;

}

【问题讨论】:

  • 尝试使用 fgets 读取字符串并循环,直到看到终止为空。

标签: c loops switch-statement word digit


【解决方案1】:

因此您可以尝试使用 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

【讨论】:

    【解决方案2】:

    最简单的方法是使用整数除法“/”和“%”从右侧使用数字。

    下面是部分代码:

    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
    }
    

    【讨论】:

    • 感谢您的评论,不幸的是,我是 c 新手,诸如递归函数和使用循环来堆栈值之类的东西对我来说完全陌生。
    • 你可以在 switch 语句中输入“digit”而不是“num”。
    【解决方案3】:

    IMO(如果不是最有效的)使用 10 次方的最容易理解的方式。如果我们以数字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 &lt;math.h&gt;。)

    【讨论】:

      【解决方案4】:

      一种可能的方法:

      #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;
      }
      

      Demo。现在解释一下:

      首先,在这里使用switch 毫无意义:数字本质上是非常线性的,因此它们的名称可以(并且应该)存储在字符串数组中(此代码中的char *digits[10] )。然后你就可以通过使用这个数字作为索引访问这个数组来获得一个特定数字的标签。

      其次,这个程序的关键问题是分别从输入中提取每个数字。从右到左更容易(取number % 10 的结果,将number / 10 分配给number,重复),但这里应该以另一种方式完成 - 从左到右。所以这就是我们所做的:

      • 计算tenth - 大于给定数字的 10 的第一个幂 (例如,如果我们使用 546,那就是 1000)
      • 在每次后续迭代中:

      --将tenth除以10

      --处理number除以tenth的整数除法

      -- 将number 的余数除以tenth 分配回number

      在第一次迭代中,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,并且循环停止 - 因为所有数字都被处理了。

      【讨论】:

        【解决方案5】:

        受@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");
        }
        

        【讨论】:

        • while 循环确实简化为 while ( isdigit(ch = getc(stdin)) ) {,但有些人发现将潜在的 EOF 传递给 is() 糟糕的风格,尽管按照规范是可以的。
        猜你喜欢
        • 2020-01-28
        • 1970-01-01
        • 1970-01-01
        • 2017-03-08
        • 2013-03-22
        • 2012-10-13
        • 1970-01-01
        • 2016-08-27
        • 1970-01-01
        相关资源
        最近更新 更多