我有一个很长的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 *,它在循环内不断更改值。
答案 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*
。