【问题标题】:How to print character array in reverse order of C program如何以C程序的相反顺序打印字符数组
【发布时间】:2015-05-05 22:29:03
【问题描述】:
#include <stdlib.h>
#include <stdio.h>
#define SIZE 25

int main (void)
{

        int d, b, c;

        printf(" Enter an integer and press 'enter':\n");
        scanf("%d" , &d);
        printf(" Enter the desired base and press 'enter':\n");
        scanf("%d" , &b);

        if (b < 2) {

                printf(" Your base is to low! \n")
        } else {

                while (d != 0) {

                        int radix;
                        radix = d % b;
                        d = d / b;
                        char basechars[] = "0123456789ABCDEF";

                        printf("%c" , basechards[radix]);
                }
        }
        return 0;
}

此程序提示用户输入小数和基数,以将该小数转换为已选择的基数。然而,转换是以相反的顺序打印的,我需要它来定期打印。示例:输入:112,然后输入 16,结果是 07 而不是 70。

【问题讨论】:

  • 将数字存储在数组中而不是打印出来,然后反向打印数组。
  • 好吧,如果挑剔的话,16 以上的基数也是有效的,并且不会被这个程序正确处理(实际上是未定义的行为)。
  • @WeatherVane 我更关心0 的表示..
  • @EugeneSh。如果您的评论与乔恩的评论有关,则根本没有标记;-)
  • @EugeneSh 0 是一个新奇事物。它根本不存在,也许现在还没有。

标签: c arrays decimal converter radix


【解决方案1】:

您可以将每个数字存储在一个数组中:

} else {
    char arr[32];
    int counter = 0;
    while (d != 0) {
        int radix;
        radix = d % b;
        d = d / b;
        char basechars[] = "0123456789ABCDEF";
        arr[counter++] = basechars[radix];
    }
    if (counter == 0)
        arr[counter++] = '0';
    arr[counter++] = '\0';
    print_rev(arr);
    printf("\n");
}

然后使用递归函数打印字符串(它将反转输出):

void print_rev(const char *s)
{
    if (*s) {
        print_rev(s + 1);
        printf("%c", *s);
    }
}

或直接:

} else {
    char arr[32];
    int counter = 0;
    while (d != 0) {
        int radix;
        radix = d % b;
        d = d / b;
        char basechars[] = "0123456789ABCDEF";
        arr[counter++] = basechars[radix];
    }
    if (counter == 0) {
        printf("0");
    else {
        while (counter--)
            printf("%c", arr[counter]);
    }
    printf("\n");
}

【讨论】:

  • 建议对d == 0进行审核。
  • 顺便说一句:将while (d != 0) { ...} 更改为do { ... } while (d != 0); 将处理d==0 的情况,而无需添加if (counter == 0)
【解决方案2】:
  1. 反转数组是最直接的方法。
  2. 使用limit.h 宏LONG_BIT 来了解需要存储的最大字符数。这会调整您的数组大小。
  3. 我也在检查 16 的上限。
  4. 构建数组,然后打印它。请注意,它可以很好地处理 0。
  5. 你也忘记了负数。

    } else if (b > 16) {
        printf(" Your base is too high! \n");
    } else {
        const char basechars[] = "0123456789ABCDEF";
    
        char arr[LONG_BIT];  // d is an integer, so LONG_BIT holds
                     // enough characters for a binary representation.
        int counter = 0;
        int negative_flag = 0;
    
        if (d < 0) {
            d = -d;
            negative_flag = 1;
        }
    
        do {
            int digit = d % b;
            d = d / b;
    
            arr[counter++] = basechars[digit];
         } while (d != 0);
    
         if (negative_flag) {
            printf ("-");
         }
    
         while (counter--) {
             printf ("%c", arr[counter]);
         }
         printf ("\n");
     }
    

【讨论】:

    【解决方案3】:

    此版本进行动态内存分配,因此您不必事先指定转换后的字符串需要多长时间。

    数字可以任意大,在二进制转换中尤其重要。我还检查了base 16,这是上限。

    int main (void)
    {
    
            int d, b, c, i = 1;
            char *converted = malloc(i);
            printf(" Enter an integer and press 'enter':\n");
            scanf("%d" , &d);
            printf(" Enter the desired base and press 'enter':\n");
            scanf("%d" , &b);
    
            if (b < 2) {
    
                    printf(" Your base is to low! \n");
                    return 1;
    
            } else if (b > 16) {
    
                    printf(" Your base is to high! \n");
                    return 1;
    
            } else {
    
                    while (d != 0) {
    
                            int radix;
                            radix = d % b;
                            d = d / b;
                            char basechars[] = "0123456789ABCDEF";
                            converted = realloc(converted, i++);
                            *(converted +i - 1) = basechars[radix];
    
                    }
            }
        i--;
        while(i != 0) {
            printf("%c", converted[i]);
            --i;
        }
        free(converted);
        printf("\n");
    
        return 0;
    }    
    

    【讨论】:

    • 是的,但您还没有解决@EugeneSh。上面的评论,关于base &gt; 16。你可以有char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 和测试if (b &lt; 2 || b &gt; 36)
    • 是的,没错,我只是假设他一直到基数 16,如果用户选择高于 16 的基数,他必须确保显示错误消息
    • 我认为这是可疑的converted = realloc(converted, i++);,因为这与您最初分配的内存相同。
    • 测试它,它工作,它是相同的内存第一次(1),然后它进入2、3、4、5,...,我还检查了base 16
    • 你用大锤敲碎坚果。通过执行char converted [sizeof(int) * CHAR_BIT + 1];,您可以知道int 中有多少个二进制数字
    【解决方案4】:

    提供递归方法。

    确定是否需要从更高的有效数字打印额外的chars,递归调用辅助函数并然后打印数字的最低有效数字。

    代码应注意将“0”作为有效输入来处理。下面使用负值来很好地处理INT_MIN

    static void PrintDigits(int x, int base) {
      static const char basechars[] = "0123456789ABCDEF";
      if (x <= -base) {
        PrintDigits(x/base, base);
      }
      putchar(basechars[-(x%base)]);
    }
    
    void PrintInt(int x, int base) {
      if (base < 2 || base > 16) {
        printf(" Your base is out of range! \n");
      } else {
        if (x < 0) putchar('-');
        else x = -x;
        PrintDigits(x, base);
      }
      putchar('\n');
    }
    
    int main(void) {
      PrintInt(65535, 16);
      PrintInt(65535, 10);
      PrintInt(65535, 2);
      PrintInt(INT_MAX, 10);
      PrintInt(0, 10);
      PrintInt(-1, 16);
      PrintInt(INT_MIN, 10);
    
      int d, b;
      printf(" Enter an integer and press 'enter':\n");
      scanf("%d" , &d);
      printf(" Enter the desired base and press 'enter':\n");
      scanf("%d" , &b);
      PrintInt(d, b);
      return 0;
    }
    

    FFFF
    65535
    1111111111111111
    2147483647
    0
    -1
    -2147483648

    即使基数为 2,递归深度也不会超过 int 的位宽。

    【讨论】:

      猜你喜欢
      • 2016-02-17
      • 1970-01-01
      • 2019-06-25
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 2014-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多