【问题标题】:Converting decimal array to binary string array with calloc使用 calloc 将十进制数组转换为二进制字符串数组
【发布时间】:2016-05-08 16:35:06
【问题描述】:

我遗漏了一些代码,但基本上我有一个小数数组,我正在尝试将其转换为二进制数,但作为字符串数组。对 C 来说是全新的,现在真的抓住了稻草。我非常不确定 malloc 和 calloc 是如何使用的。这是我试图让它为第一个数字/二进制字符串工作的尝试:

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

void binstringconvert (unsigned long int *decimals, char **binarystrings);


int main (int argc, char **argv) 
{
    // initialize variables
    int numLines = 9;
    int binaryLength = 32;
    unsigned long int decimals[numLines];   
    decimals[0] = 3241580200;   

    // convert decimal array to 32-bit binary string array
    char **binarystrings = calloc (numLines, binaryLength);
    binstringconvert(decimals, binarystrings);  

    // test print
    printf("\n\n%lu in binary number system is: ", decimals[0]);
    printf("\n%s", binarystrings[0]);   
}

void binstringconvert (unsigned long int *decimals, char **binarystrings)
{
    int c, k;

    for (c = 31; c >= 0; c--)
    {
        k = decimals[0] >> c;    
        if (k & 1)
            binarystrings[0][c] = '1';
        else
            binarystrings[0][c] = '0';
    }       
}

我是否正确初始化了binarystrings?我是否能够按照我尝试的方式写入单个字符?目前它给了我一个段错误。

【问题讨论】:

  • 不要只将大小硬编码到calloc()。指定元素的数量每个元素的大小(使用sizeof()运算符)。
  • 我现在放了一个变量
  • binarystrings[0] 未初始化。
  • 你真的需要一个指向字符串的指针数组吗?你只使用过binarystrings[0]
  • 这只是一个测试用例,我实际上有一个来自文本文件的小数数组。在我让它为binarystrings[0] 工作后,我的计划是为其余索引围绕它放置一个 for 循环。

标签: c arrays string binary calloc


【解决方案1】:

抱歉,我解释说您想将多个数字传递给您的函数并将它们全部转换为二进制字符串并返回。无论如何,这个例子仍然有效。无论哪种情况,要将 32 位数字放入字符串中,您需要 33 个字符(nul-terminating 字符为 +1)。此外,您正在以相反的顺序编写二进制字符串。

只需稍作调整即可更正顺序。示例:

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

enum { DWRD = 32 };

void binstringconvert (unsigned *decimals, char (*binarystrings)[DWRD+1], int n);

int main (void)
{
    /* initialize variables */
    unsigned int decimals[] = { 1, 255, 65535, 8388607,
                                3241580200, 2898560974,
                                4294967295, 3097295382,
                                1076482445, 1234567890 };
    char (*binarystrings)[DWRD+1] = {NULL};
    int i, n = sizeof decimals/sizeof *decimals;

    binarystrings = calloc (n, sizeof *binarystrings);
    binstringconvert (decimals, binarystrings, n);

    /* test print */
    for (i = 0; i < n; i++)
        printf (" %10u : %s\n", decimals[i], binarystrings[i]);

    free (binarystrings);

    return 0;
}

void binstringconvert (unsigned *decimals, char (*binarystrings)[DWRD+1], int n)
{
    int c, i, k;
    for (i = 0; i < n; i++) {
        for (c = 31; c >= 0; c--)
        {
            k = decimals[i] >> c;
            if (k & 1)
                binarystrings[i][31-c] = '1';
            else
                binarystrings[i][31-c] = '0';
        }
        binarystrings[i][DWRD] = 0;  /* nul-terminate */
    }
}

输出

$ ./bin/binstrings
          1 : 00000000000000000000000000000001
        255 : 00000000000000000000000011111111
      65535 : 00000000000000001111111111111111
    8388607 : 00000000011111111111111111111111
 3241580200 : 11000001001101101001011010101000
 2898560974 : 10101100110001001000011111001110
 4294967295 : 11111111111111111111111111111111
 3097295382 : 10111000100111001111101000010110
 1076482445 : 01000000001010011101000110001101
 1234567890 : 01001001100101100000001011010010

【讨论】:

  • 当然,我通常以不同的方式处理二进制转换,但没有理由不能按照您的方式进行操作:)
  • 我以前总是用 2 种方式完成 mod,但我想尝试一些不同的东西,因为除了最简单的按位运算外,我什么都不擅长
【解决方案2】:

您需要为字符串指针数组以及字符串本身分配空间。第一次调用calloc() 分配指向字符串的指针数组,每个malloc() 自己分配字符串:

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

void binstringconvert (unsigned long int *decimals, char **binarystrings);


int main (int argc, char **argv) 
{
    // initialize variables
    int numLines = 9;
    int binaryLength = 32;
    unsigned long int decimals[numLines];   
    decimals[0] = 3241580200;
    int i;

    // Allocate an array of numLines pointers to strings
    char **binarystrings;
    if ( (binarystrings = calloc(numLines, sizeof(*binarystrings))) == NULL )
      return EXIT_FAILURE;

    // Allocate space for each string
    // binaryLength bits plus one for null terminator
    for ( i=0; i<numLines; ++i ) {
      if ( (binarystrings[i] = malloc((binaryLength + 1)*sizeof(**binarystrings))) == NULL )
        return EXIT_FAILURE;
    }

    // convert decimal array to 32-bit binary string array
    binstringconvert(decimals, binarystrings);  

    // test print
    printf("\n\n%lu in binary number system is: ", decimals[0]);
    printf("\n%s", binarystrings[0]);   
}

void binstringconvert (unsigned long int *decimals, char **binarystrings)
{
    int c, k;

    for (c = 31; c >= 0; c--)
    {
        k = decimals[0] >> (31 - c);    
        if (k & 1)
            binarystrings[0][c] = '1';
        else
            binarystrings[0][c] = '0';
    }
    binarystrings[0][32] = '\0';
}

另外,您没有在字符串末尾写入空终止符。当您尝试编写它时(printf("\n%s", binarystrings[0]);),它将继续读取内存,超过您希望结束的位置。在末尾写入零 ('\0') 需要在分配中增加一个字符,因此 malloc() 调用中的 +1

注意sizeof() 运算符的使用。您永远不应该对内存大小进行硬编码。在 C 中,让编译器弄清楚事情有多大,不要试图猜测。一个指针在 32 位系统上可以是 4 个字节,在 64 位系统上可以是 8 个字节。即使您知道您拥有什么系统以及它有多大,也请使用sizeof()

编辑:更正了@DavidCRankin 注意到的逻辑错误:

        k = decimals[0] >> (31 - c);    

【讨论】:

  • 嗯..我仍然遇到段错误,也许我没有正确执行此操作?我将 binaryLength 更改为 33 并添加了 binarystrings[0][32] = '\0';
  • 你在写你的二进制数...尝试传递1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 2015-06-14
  • 1970-01-01
  • 2020-04-28
相关资源
最近更新 更多