【问题标题】:base 4 to base 2 converter基数 4 到基数 2 转换器
【发布时间】:2012-10-27 13:21:50
【问题描述】:

这个程序是将基数为 4 的数转换为基数为 2 的数,它应该就地完成

#include<stdio.h>
#include<string.h>

void shiftr(char num[],int i)
{
     memmove(num+i,num+i+1,strlen(num)-i);
}

char* convert4to2(char num[])
{
int i=0,len;
char ch;

    while(num[i]!='\0')
    {
        ch=num[i];
        shiftr(num,i);
        switch(ch)
        {
            case '0':num[i++]='0';
                 num[i++]='0';
                 break;

            case '1':num[i++]='0';
                 num[i++]='1';
                 break;

            case '2':num[i++]='1';
                 num[i++]='0';
                 break;

            case '3':num[i++]='1';
                 num[i++]='1';
                 break;

            default:printf("Error");
        }
    }

    num[i]='\0';
    return(num);
}



void main()
{
    char num[20];
    printf("Enter the Base 4 Number:");
    scanf("%s",&num);
    printf("The Binary Equivalent is:%s\n",convert4to2(num));   
}

输入 121(以 4 为基数)的输出应该是 011001,但它只显示 01。 对于像 12101 这样的较大数字,它会显示 0100,取第一个和最后一个数字。 可能是什么问题呢?

【问题讨论】:

  • 这个shiftr() 功能首先很痛苦。
  • @H2CO3 但必须到位
  • 从字符串末尾转换(首先确保数组有空间)。
  • 我认为你弄错了void *memmove(void *dest, const void *src, size_t n); 的参数顺序。你是在左移,而不是右移。

标签: c output memmove


【解决方案1】:

您正在积极破坏您的输入。例如,对于第一次迭代,您将您的数字移动一个位置,然后用您的第一个数字的二进制输出覆盖第 0 位和第 1 位(包含 4 基数中的下一个 2 位)的数据。

【讨论】:

  • 啊!工作谢谢。前两个 memmove 参数应该互换。
  • @MaheshOstwal 交换两个参数后,您是否在长度上加了一个? (也移动最后一个空字节)并检查 num 是否足够长以在转换后存储。
  • 是的。谢谢。长度加一,增加num的大小。
【解决方案2】:

您可以将字符串放入strtol 函数中,而不是使用字符直接从基数4 转换为基数2,该函数将任意基数的整数字符串转换为long。从那里很容易打印出二进制表示。

编辑:示例:

char* convert4to2(const char input[], char *output, const size_t output_length)
{
    /* First make sure the output string is long enough */
    if (output_length < (sizeof(long) * 8 + 1))  /* +1 for '\0' */
        return NULL;  /* Not enouth space */

    /* Convert from the input string to a `long` */
    long value = strtol(input, NULL, 4);  /* The last `4` is the base of the input string */

    /* Convert the number to binary */
    char *output_ptr = output;

    /* Multiply with 8 to get the number of bits */
    /* Subtract 1 because bits a numbered from zero */
    for (int bit = sizeof(long) * 8 - 1; bit >= 0; bit--)
    {
        /* `value >> bit` make the current bit the lowest bit */
        /* `& 1` to mask out all but the lowest bit */
        /* `+ '0'` to make it a proper character digit */
        *output_ptr++ = ((value >> bit) & 1) + '0';
    }

    /* Terminate the string */
    *output_ptr = '\0';

    /* Return the converted string */
    return output;
}

这样称呼它:

const char num[] = "121";
char output[65];  /* `long` can be 64 bits, plus one for the string terminator */

printf("%s in base 4 is %s in base 2\n",
    num, convert4to2(num, output, sizeof(output)));

【讨论】:

  • 据我了解,您的意思是将其转换为长基数 10 值,然后最终转换为二进制形式?如果这就是您的建议,那么“就地”执行它是有限制的。 (如果我理解错了请回复,我只是新手)。
  • @MaheshOstwal strtol 采用任何基数(例如基数 4)的字符串并将其转换为本机 long。将long 打印为二进制数字非常容易。请参阅我的 working example 示例。
【解决方案3】:

无需向上移动,只需向后工作:

#include <stdio.h>
#include <string.h>

void convert4to2(char *str)
{
size_t idx;
char ch;
static char *conv[4] = {"00", "01","10", "11" };

idx = strlen(str);
str[idx*2] = 0;

while(idx--) {
    ch=str[idx];
    if (ch < '0' || ch > '3') return; /* replace by relevant error handler */
    memcpy(str+2*idx, conv[ ch - '0' ], 2 );
    }

return;
}

int main(void)
{
char quad[21] = "0123321023" ;

printf("Old:%s\n", quad);
convert4to2(quad);
printf("New:%s\n", quad);

return 0;
}

【讨论】:

  • 谢谢。这更优雅。
猜你喜欢
  • 1970-01-01
  • 2011-09-09
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 2014-04-15
  • 2017-08-14
  • 2019-05-18
相关资源
最近更新 更多