【问题标题】:Splitting a sequence of binary digits based on inputs in c根据c中的输入拆分二进制数字序列
【发布时间】:2018-09-16 21:53:53
【问题描述】:

我有一个代表地址的二进制数字数组。我现在想将此地址分成 3 个部分或数组,它们是 tagindexoffset,这三个部分的位数由用户确定。 为了更清楚,这是代码:

char* bin_val_addr;
while(fscanf(FP, "%s %lx", str, &addr) != EOF)
{

    bin_val_addr = long_to_binary(addr);

    char* array_Tag = malloc(no_Tag_bits * sizeof(char*));
    char* array_Index = malloc(no_Index_bits * sizeof(char*));
    memcpy(array_Tag, bin_val_addr, no_Tag_bits * sizeof(char*));
    memcpy(array_Index, bin_val_addr, no_Index_bits * sizeof(char*));
    printf("TAG array is: %s\n", array_Tag);
    printf("INDEX array is: %s\n", array_Index);


}

而long_to_binary函数如下:

char* long_to_binary(unsigned long k)
{
        static char c[65];
        c[0] = '\0';

        unsigned long val;
        for (val = 1UL << (sizeof(unsigned long)*8-1); val > 0; val >>= 1) 
        {        
            strcat(c, ((k & val) == val) ? "1" : "0");
        }
        return c;
}

我查找了拆分数组的方法,发现可以使用memcpy,但是在实现它时我在某个地方出错了。有人可以帮我吗?

【问题讨论】:

  • 例如,如果您想在字符串中存储 1010,那么该字符串的长度至少需要 5 个字符(4 个字符用于保存 1010,1 个字符用于保存字符串的空终止符)。您的代码在应该分配 5 个字符时错误地分配了 4 个字符指针。这里还有其他问题,例如从 long_to_binary() 函数返回 'c' 的方式需要改变。
  • 好的,所以我必须更改 sizeof(char*) 语句对吗?
  • 是的,如果你想分配一个可以容纳N个字符的字符串那么你需要malloc(N+1),而不是malloc(N * sizeof(char *))。
  • 为什么我返回 c 的方式不对?
  • 啊,它是静态的。之前没有注意到。在那种情况下没关系(我不是一个大粉丝,但它会起作用)。

标签: c arrays


【解决方案1】:

如果bin_val_addr包含1s0s的序列,顺序为tagindexoffset,则以下副本来自@987654327的开头 @ 用于array_Tagarray_Index,例如

    memcpy(array_Tag, bin_val_addr, no_Tag_bits * sizeof(char*));
    memcpy(array_Index, bin_val_addr, no_Index_bits * sizeof(char*));

如果array_Indexbin_val_addr之后 array_Tag 开始,那么您需要将array_Index 的来源偏移no_Tag_bits

(请注意您正在混合位和字节(您有字符 '1''0' 而不是位)。因此,除非您需要每个字符 8-bytes,否则 sizeof(char*) 应该是sizeof(char)——它总是1,应该从你的分配中删除)

例如,分配以保存每个数组中指定的 字符+1 表示 nul-terminating 字符),您可以这样做:

    char *array_Tag = malloc(no_Tag_bits + 1);
    char *array_Index = malloc(no_Index_bits + 1);

并且您必须验证每个分配,因为 malloc 可以并且将无法在内存耗尽时返回 NULL,例如

    if (!array_Tag) {
        perror ("malloc-array_Tag");
        exit (EXIT_FAILURE);
    }

将这些部分放在一起并nul-terminating每个字符串,您将拥有:

    memcpy (array_Tag, bin_val_addr, no_Tag_bits);
    array_Tag[no_Tag_bits] = 0;
    memcpy (array_Index, bin_val_addr + no_Tag_bits, no_Index_bits);
    array_Index[no_Index_bits] = 0;

现在可以将数组输出为字符串

    printf ("TAG array is: %s\n", array_Tag);
    printf ("INDEX array is: %s\n", array_Index);

最后,您对fscanf 的使用会在匹配输入 失败时引发未定义行为,其中少于指定的转换总数发生。而不是检查EOF,您应该使用指定的实际发生的转化次数进行验证,例如

while (fscanf (FP, "%s %lx", str, &addr) == 2)

进行这些更改后,假设您的 long_to_binary 正在按您的预期工作,如果您还有其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多