【问题标题】:How to convert an int to a series of characters如何将int转换为一系列字符
【发布时间】:2011-10-04 23:23:06
【问题描述】:

我正在尝试将 8 位微控制器(PIC)上的 C 整数分解为其 ASCII 等效字符。

例如: 将 982 转换为 '9','8','2'

到目前为止,我想出的一切似乎都是蛮力的。这是我现在基本上在做的主要思想:

if( (10 <= n) && (n < 100) ) {
// isolate and update the first order of magnitude
digit_0 = (n % 10);
// isolate and update the second order of magnitude
switch( n - (n % 10) ) {
  case 0:
    digit_1 = 0;
    break;
  case 10:
    digit_1 = 1;
    break;

...

然后我有另一个函数,只需将 0b00110000(48 进制)添加到我的每个数字。

我一直无法找到任何 C 函数来为我做这件事或我自己做得很好。

提前感谢您的帮助!

【问题讨论】:

    标签: c integer ascii character pic


    【解决方案1】:

    如果sprintf 因某种原因不适合,像这样简单的方法会起作用:

    char digits[MAX_DIGITS];
    int count = 0;
    do {
        digits[count++] = n % 10;
        n /= 10;
    } while (n > 0);
    

    会有count 数字,digits[0] 是最不重要的。

    【讨论】:

    • +1 这正是他所需要的!我已经发布了在汇编程序中制作的相同功能。
    【解决方案2】:

    要自己做,您需要执行以下示例代码演示的操作:

    #include <stdio.h>
    
    int main (void)
    {
      unsigned int x = 512;
      int base_val = 10, digit, i = 0, n = 0;
      char x_str[32], t;
    
      printf ("\nEnter an unsigned number: ");
      scanf ("%u", &x);
    
      printf ("\nEnter base: ");
      scanf ("%d", &base_val);
    
      /* Chop the digits in reverse order and store in `x_arr`
       * the interpretation of the digits are made in base value
       * denoted by `base_val`
       */
    
      while (x)
      {
        digit = x % base_val;
        x /= base_val;
        if (digit < 10)
          x_str[n++] = digit + '0';
        else
          x_str[n++] = digit + 'A' - 10;  /* handle base > 9 */
      }
    
      /* Terminate string */
      x_str[n] = '\0';
    
      /* Reverse string */
      for (i=0; i<n/2; i++)
      {
        t = x_str[i];
        x_str[i] = x_str[n-i-1];
        x_str[n-i-1] = t;
      }
      printf ("\n%s\n", x_str);
    
      return 0;
    }
    

    while 循环将从给定基数的整数中删除数字,并将数字以相反的顺序输入数组中。内部if - else 处理大于9 的基数,并在数字值大于10 时放置大写字母。for 循环将字符串反转并按正序将切碎的数字转换为字符串。

    您需要根据您的最大能力调整x_str 数组的大小。为它定义一个宏。请注意,上面的代码仅适用于无符号整数。对于有符号整数,您需要首先检查它是否低于 0,然后在 x_str 中添加一个“-”符号,然后打印大小,即。使用 -x 应用上述代码。这也可以通过检查符号位,通过掩码来完成,但会使过程依赖于整数的存储。

    base_val 是您要解释数字的基数。

    【讨论】:

    • 它是一个微控制器。您的代码有效,但 printf 和 scanf 可能不可用。
    • 以上代码只是一个演示,用于演示while循环和for循环的工作原理。
    【解决方案3】:

    我很久以前就回答过这样的问题。

    Implementing ftoa

    我希望这会有所帮助。这适用于整数和浮点数。这个概念很简单。

    1. 确定位数(对于以 10 为底,您使用以 10 为底的对数)
    2. 通过取 (num/digit_weight) 的下限来获取 msb 数字
    3. 从数字中减去数字 * 重量,重量减 1
    4. 再做一次,直到 number == 0(整数)或 num > 0 + fp 数的容差

    由于算法每次迭代都会处理一个数字,因此它的 O(logn) 时间非常合理。

    【讨论】:

    • Tarabyte 使用小型 8 位 MCPU 和几千字的 FLASH 程序存储器,因此在这种情况下使用日志功能是不合理的。我的函数只使用了 17 个字的程序内存,而且速度快、简短且有效,并且很容易包含在 c 或任何其他语言中。
    【解决方案4】:

    如果您与 PIC16 RISC 汇编器兼容,那么这将非常简单、快速、简短且有效。在这里你有 16 位无符号 16 位除以 10 rutine 看看怎么做。

    要获得 WREG 中数字的第一个最低字符,请将 16 位无符号数放入 Reg1 和 Reg2 并调用 rutine。再次获取下一个字符调用 rutine 以此类推,直到 Reg1 和 Reg2 为 0。

    RegAE       res 1
    RegA0       res 1
    RegA1       res 1
    RegA2       res 1
    
    
    
        divR16by_c10
        ;{
        ;//Input: 16 bit unsigned number as RegA1,2 (RegA2 low byte, RegA1 High byte)
        ;//Division result: Reg1 and Reg2 and reminder as char in WREG
                clrf    RegA0
                movlw   16             ;//init loop counter
                movwf   RegAE
                lslf    RegA2, f
        divI16by_c10_        
                rlf     RegA1, f
                rlf     RegA0, f       
                movlw   10
                subwf   RegA0, f
                btfsc   Carry
                bra     divI16by_c10_OK
                addwfc  RegA0, f
                bcf     Carry
        divI16by_c10_OK        
                rlf     RegA2, f
                decfsz  RegAE, f
                bra     divI16by_c10_
        ;//result= W from 0..9
                addlw   0x30        ;//convert to char
                return 
        ;}
    

    编辑:

    如果要转换有符号 16 位值,请先检查第 15 位,以确定符号数。如果比写负数 - 签署并否定 RegA1,2 中的数字。之后的过程与正数相同。 要否定数字,您可以使用以下 asm rutine:

                 comf    RegA2, f
                 comf    RegA1, f
                 movlw   0
                 bsf     STATUS, 0      ;//set carry flag
                 addwfc  RegA2, f
                 addwfc  RegA1, f 
    

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 2011-03-11
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      • 2015-11-12
      相关资源
      最近更新 更多