子集char数组而不在C ++中复制它

时间:2018-12-01 14:11:55

标签: c++ arrays

我有一个很长的char数组(通过GDAL来自栅格文件),全部由0和1组成。要压缩数据,我想将其转换为位数组(因此将大小除以8) ,一次4个字节,将结果写入另一个文件。这是我现在想出的:

"workbench.colorCustomizations": {
  "[Material Theme Palenight High Contrast]": {
    "editorError.foreground": "#FF5370",
    "editorHint.foreground": "#C3E88D",
    "editorLineNumber.foreground": "#676E95",
    "editorLineNumber.activeForeground": "#80CBC4",
    "gitDecoration.deletedResourceForeground": "#FF5370",
    "gitDecoration.conflictingResourceForeground": "#FFCB6B",
    "gitDecoration.modifiedResourceForeground": "#82AAFF",
    "gitDecoration.untrackedResourceForeground": "#C3E88D"
  },
  "[One Dark Pro]": {
    "editor.background": "#2c313a"
  }
},

代码正在运行,结果将被写入一个单独的文件中。我想知道的是:我可以在不将字符复制到新数组的情况下做到这一点吗?

编辑:我在这里使用const变量只是为了制作一个最小的,可重复的示例。在我的程序中,它是一个char *,它在循环内不断更改值。

4 个答案:

答案 0 :(得分:2)

是的,您可以,只要您可以修改源字符串(在您的示例代码中就不能,因为它是一个常量,但实际上我认为您的字符串在可写内存中):

uint32_t bytes2bits(const char* b) {
    return strtoul(b,0,2);
}

void compress (char* data) { 
    // You would need to make sure that the `data` argument always has 
    // at least 33 characters in length (the null terminator at the end 
    // of the original string counts)
    char temp = data[32];
    data[32] = 0;
    uint32_t byte = bytes2bits(data);
    data[32] = temp;
    printf("Data: %d\n",byte); // 128
}

答案 1 :(得分:1)

在此示例中,通过使用char *作为存储长数据的缓冲区,没有必要将所有部分都复制到临时缓冲区中以将其转换为long。 只需使用变量在每个32个字节的长度周期内逐步通过缓冲区,但是在第32个字节之后需要0终止字节。

所以您的代码如下:

uint32_t bytes2bits(const char* b) {
    return strtoul(b,0,2);
}

void compress (char* data) { 
    int dataLen = strlen(data);
    int periodLen = 32;
    char* periodStr;
    char tmp;
    int periodPos = periodLen+1;
    uint32_t byte;

    periodStr = data[0];
    while(periodPos < dataLen)
    {
    tmp = data[periodPos];
    data[periodPos] = 0;

    byte = bytes2bits(periodStr);
    printf("Data: %d\n",byte); // 128

    data[periodPos] = tmp;
    periodStr = data[periodPos];
    periodPos += periodLen;
    }
    if(periodPos - periodLen <= dataLen)
    {
        byte = bytes2bits(periodStr);
        printf("Data: %d\n",byte); // 128
    }
}

请注意最后一个时间段,该时间段可能小于32个字节。

答案 2 :(得分:0)

  

const char data[36]

如果将某些内容声明为const,然后对其进行修改,则会违反与编译器的合同。

通常来说,编译器不会让您对其进行修改...因此,即使要使用const声明进行 try 修改,也必须将其强制转换为(但不要t)

char *sneaky_ptr = (char*)data;
sneaky_ptr[0] = 'U'; /* the U is for "undefined behavior" */

请参阅:this

因此,如果要执行此操作,则必须确保数据合法地是非常量的。

答案 3 :(得分:0)

在现代C ++中,执行此操作的正确方法是使用std::string来保存您的字符串,并使用std::string_view来处理该字符串的某些部分而无需复制它。

您可以将string_view与该char数组一起使用。通常使用它来更新经典的以空值结尾的字符串const char*