C++ 为什么strtoul从“0”返回0;1“;一串
我正在尝试以一种不用GDAL库就能轻松阅读的方式压缩光栅文件(我的web服务器无法安装GDAL)。接下来,我将执行以下操作以将光栅的字节(仅0和1值)转换为位:C++ 为什么strtoul从“0”返回0;1“;一串,c++,arrays,pointers,strtoul,C++,Arrays,Pointers,Strtoul,我正在尝试以一种不用GDAL库就能轻松阅读的方式压缩光栅文件(我的web服务器无法安装GDAL)。接下来,我将执行以下操作以将光栅的字节(仅0和1值)转换为位: intmain(intargc,char*argv[]){ 如果(argcGetRasterXSize(),ty=poDataset->GetRasterYSize(); GDALRasterBand*poBand; int nBlockXSize,nBlockYSize; poBand=poDataset->GetRasterBand
intmain(intargc,char*argv[]){
如果(argc<3){
返回1;
}
GDALDataset*poDataset;
GDALAllRegister();
poDataset=(GDALDataset*)GDALOpen(argv[1],GA_只读);
if(poDataset==NULL){
返回2;
}
int tx=poDataset->GetRasterXSize(),ty=poDataset->GetRasterYSize();
GDALRasterBand*poBand;
int nBlockXSize,nBlockYSize;
poBand=poDataset->GetRasterBand(1);
printf(“类型:%s\n”,GDALGetDataTypeName(poBand->GetRasterDataType());
//类型:字节
poBand->GetBlockSize(&nBlockXSize,&nBlockYSize);
int i,nX=tx/nBlockXSize,nY=ty/nBlockYSize;
char*data=(char*)CPLMalloc(nBlockXSize*nBlockYSize+1);
uint32_t out[nBlockXSize*nBlockYSize/32];
焦炭温度;
cplererro;
文件*pFile;
pFile=fopen(argv[2],“wb”);
对于(y=0;y 0){
返回3;
}
for(i=0;istrtoul
用于将可打印字符数据转换为整数。字符串应包含数字字符代码,例如'0'
,'1'
等
显然,在您的例子中,源数据实际上是整数值1
,因此strtoul
发现没有预期形式的字符,并返回0
%d
是out[i/32]的错误格式说明符
,这会导致未定义的行为strtoul
将字符序列转换为数字,因此第一个字符是1
,实际上不会告诉您多少,例如,可能字符串是1000000000000000000
。在这种情况下,它应该返回ULONG\u MAX
(因为输入是正确的二进制数,但超出了范围)而不是0
;0
的返回值应该表示没有找到任何数字,或者该值实际上是0
。您可以尝试更改调试打印以显示更多字符,例如printf(%.20s“,&data[i])
(假设它都包含可打印字符),或者在debuggerOK中检查,这更有意义…数据[i]
是1
(不是'1'
)因此,strtoul
没有匹配字符,因此返回了0
。您了解char x=1;
和char x='1';
之间的区别吗?您都有一个未定义的行为。除非CPLMalloc
比您要求的多给您一个字节,否则data[i+32]
将到达分配给数据的内存之外
int main(int argc,char *argv[]) {
if (argc < 3) {
return 1;
}
GDALDataset *poDataset;
GDALAllRegister();
poDataset = (GDALDataset*)GDALOpen(argv[1],GA_ReadOnly);
if (poDataset == NULL) {
return 2;
}
int tx=poDataset->GetRasterXSize(), ty=poDataset->GetRasterYSize();
GDALRasterBand *poBand;
int nBlockXSize,nBlockYSize;
poBand = poDataset->GetRasterBand(1);
printf("Type: %s\n",GDALGetDataTypeName(poBand->GetRasterDataType()));
// Type: Byte
poBand->GetBlockSize(&nBlockXSize,&nBlockYSize);
int i, nX = tx/nBlockXSize, nY = ty/nBlockYSize;
char *data = (char*)CPLMalloc(nBlockXSize*nBlockYSize + 1);
uint32_t out[nBlockXSize*nBlockYSize/32];
char temp;
CPLErr erro;
FILE* pFile;
pFile = fopen(argv[2],"wb");
for (y=0; y<nY; y++) {
for (x=0; x<nX; x++) {
erro = poBand->ReadBlock(x,y,data);
if (erro > 0) {
return 3;
}
for (i=0; i<nBlockXSize*nBlockYSize; i+=32) {
temp = data[i+32];
data[i+32] = 0;
out[i/32] = strtoul(&data[i],0,2);
if (data[i] != 0) {
printf("%u/%u ",data[i],out[i/32]);
}
data[i+32] = temp;
}
ch = getchar(); // for debugging
}
fwrite(out,4,nBlockXSize*nBlockYSize/32,pFile);
}
fclose(pFile);
CPLFree(data);
return 0;
}