将 char 数组转换为等效整数,反之亦然

标签 c string int

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

为了做到这一点,我的想法是使用以下函数将我的字符数组转换为 4 个字符 block 中的整数值(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 位数字)。

最佳答案

我对您的目标的理解是,您希望将一个以空字符结尾的字符 block 存储到一个由整数组成的虚拟磁盘中,放入 block 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 类型已签名的情况下进行符号传播,这是许多系统的默认设置系统。
  • 您应该将写入的 block (j) 中的数字返回给调用者。这是有用的信息,可以很容易地与错误的 -1 区分开来。
  • 此代码确实假定char 有 8 位。使用 CHAR_BITS 而不是 8 将允许其他值和一些其他不断调整,如果你真的寻求与异国情调的平台完全兼容。
  • 我使用 unsigned long long 算法来允许存储单元尽可能大。

关于将 char 数组转换为等效整数,反之亦然,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35533765/

相关文章:

mysql - MySQL创建列时是否需要指定INT的最大长度?

java - 使用 getIntent() 时 int 和 string 之间的冲突

c# - 将 2 个字节转换为有符号整数

c - 如何在 OpenGL 中获取矩阵堆栈的当前大小?

Java:计算字符串中序列的频率

python - Python3 中德语元音变音的编码/解码

ruby - 从 ruby​​ 中的字符串中删除空行

c - 为什么填充基于数据类型

c - 如何访问不相关和以前运行的进程的标准输入/标准输出?

if 条件到三元运算符的转换