我有一个BTLE设备,它向我发送字节,其中一些我需要组成一个32位有符号的int,转换,然后解释。我正在使用xcode 6.1。
我遇到的问题是使用sscanf简单地将字节转换为int32_t,这有时可以工作,有时却不能。我不是一个obj-c专家,不确定这是否是正确的方法,使用strtol同样不起作用。
整个功能如下:
- (double) parseMV2: (NSData*) data {
NSData* slicedData = [data subdataWithRange:NSMakeRange(2, 4)];
const char *bytes = [slicedData bytes];
int32_t value;
double mV = 0;
int sscanf_result = sscanf(bytes, "%4x", &value);
if (1 == sscanf_result) {
value <<= 3; // discard the 3 most significant bits as they are not part of the value this also brings the sign bit to the most significant bit position.
value >>= 8; // discard the 5 least significant bits as they are below the noise levels.
mV = ((double)value)*2048.0/16777216.0; // Convert to mV
} else {
NSLog(@" sscanf failed to read bytes %4x (result = %d)", (int32_t) bytes, sscanf_result);
}
NSLog(@" mV2 = %f (bytes = %x", mV, (uint) bytes);
NSLog(@"----------------------------------");
return mV;
}
如果我在sscanf之后设置断点,有时将值设置为正确的字节解释,但通常只设置为零。这是llvm的一些输出:
(lldb) print bytes
(const char *) $3 = 0x17ecceb8 "+\333\x91"
(lldb) print value
(int32_t) $4 = 0
这是另一个例子,其中sscanf再次返回0但值不为0(因为我认为sscanf返回它实际指定的变量数量,所以不要这样做):
(lldb) print bytes
(const char *) $6 = 0x176db558 ")Z\x19x"
(lldb) print value
(int32_t) $7 = 383772
答案 0 :(得分:4)
使用sscanf
用于从C字符串中读取,但您没有C字符串。你有一个字节序列。
以这种方式尝试:
NSData* slicedData = [data subdataWithRange:NSMakeRange(2, 4)];
const uint8_t *bytes = [slicedData bytes];
int32_t value;
memcpy(&value, bytes, 4);
正如Ken所指出的,更简单的方法是:
int32_t value;
[data getBytes:&value range:NSMakeRange(2, 4)];
您可能还需要担心字节排序,具体取决于数据的创建方式。您可能需要添加:
value = CFSwapInt32BigToHost(value); // or CFSwapInt32LittleToHost