【问题标题】:Convert char array to integer equivalent and vice-versa将 char 数组转换为等效整数,反之亦然
【发布时间】:2016-02-21 08:06:53
【问题描述】:

我正在尝试构建一个简单的函数来处理“假”磁盘上的块条带化(在内存中实现为由 4 字节整数表示的 n 个 x 字节块的嵌套数组,在关闭时存储到常规文件中)。数据从我的打开文件表 (OFT) 的缓冲区中作为字符数组传递到我的 write_block 函数中。

为了做到这一点,我的想法是使用以下函数将我的字符数组转换为 4 个字符块中的整数值(4x1 字节字符的逻辑相当于 1x4 字节整数):

//write_block(index, block_pointer)
//  write block, start with array of characters and write integers to ldisk (convBlock == converted Block)
//      return: 1 if successful, -1 if not
int write_block(int blockIndex, char *convBlock) {
    if (strlen(convBlock) > blockSize) {
        printf("Block passed to write exceeds max block size\n");
        return -1;
    }

    int i, j;
    int scalar, currIndex;
    for (i = 0; i < strlen(convBlock) / sizeof(int) + ((strlen(convBlock) % sizeof(int) == 0) ? 0 : 1); i++) {
        scalar = 1;
        for (j = 0; j < sizeof(int); j++) {
            currIndex = (i * sizeof(int) + j);
            if (currIndex > strlen(convBlock))
                break;
            ldisk[blockIndex][i] += convBlock[i] * scalar;
            scalar *= 1000;
        }
    }
    return 1;
}

但是,这不起作用,因为无符号 4 位整数的最大大小为 4294967295(10 位),而以这种方式转换 char 数组会产生 12 位(每个字符 3 个)。我知道从技术上讲我应该能够做到这一点,因为 char 占用一个字节,而整数占用 4。

我的下一个想法是转换为二进制,然后再转换回整数。但是,我需要以某种方式背靠背存储 4 个字符的二进制表示,这需要一个 4*8 = 32 位的整数,而最大数字类型 (long long) 的最大大小是 18446744073709551615 (20位数)。

【问题讨论】:

  • @Rabbid76 那么要转换回来,你会分出 256 的倍数吗?
  • 恐怕你的问题不清楚。你想用这些数据块做什么?
  • @chqrlie 我试图将它们放在一个名为 ldisk 的数组中,该数组由int ldisk[numBlocks][blockSize/sizeof(int)]初始化
  • 好的,但是为什么你的虚拟磁盘是由 4 个字节的 int 元素而不是字节组成的呢?为什么你甚至认为int 是4 个字节,你为什么要使用签名int?您如何将数据切成块...您的规范丢失了。
  • 你能把任意长的字符串传给write_block吗?

标签: c string int


【解决方案1】:

我对您的目标的理解是您希望将一个以空字符结尾的字符块存储到由整数组成的虚拟磁盘到块 blockIndex 中。

这是您的函数的简化版本,可以处理不同的存储类型:4 字节整数或 8 字节整数:

#include <stdint.h>

//write_block(index, block_pointer)
//  write block, start with array of characters src and write integers to ldisk
//      return: 1 if successful, -1 if not
int write_block(int blockIndex, const char *src) {
    size_t i, j, k, size;

    size = strlen(src) + 1;  // include the null terminator in the written conversion.
    if (size > blockSize) {
        printf("Block passed to write exceeds current block size\n");
        return -1;
    }
    for (i = j = k = 0; i < size; i++) {
        ldisk[blockIndex][j] &= ~(0xFFULL << k);
        ldisk[blockIndex][j] |= (unsigned long long)(unsigned char)src[i] << k;
        k += 8;
        if (k == sizeof(ldisk[blockIndex][j]) * 8) {
            j++;
            k = 0;
        }
    }
    return 1;
}

注意事项:

  • 我在转换中包含了空终止符,以便读取代码知道在哪里停止。
  • char 值必须转换为 unsigned char 以避免符号传播,以防 char 类型已签名,这是许多系统的默认设置。
  • 如果块写入 (j) 给调用者,您应该返回数字。这是有用的信息,很容易与错误的 -1 区分开来。
  • 此代码确实假定char 有8 位。如果您确实寻求与外来平台的完全兼容性,则使用 CHAR_BITS 而不是 8 将允许通过其他一些不断调整的其他值。
  • 我使用unsigned long long 算法来允许存储单元尽可能大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-01
    • 1970-01-01
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-15
    • 2014-01-23
    相关资源
    最近更新 更多