我最近继承了一些Objective代码,对它的实际操作感到困惑吗?
1)我不明白为什么char byte_chars[3]
先填充'0‘,最后再填充’0‘?
2)我不明白为什么他们用unsigned char
作为wholeByte,但他们投入了很长的时间吗?
3)我的一部分对strtol方法在这里做什么有点困惑,它需要3个byte_chars字节(它们是十六进制),然后将它们转换为一个长字节?
- (NSString *)starFromFlags:(NSString *)flags {
unsigned char wholeByte;
char byte_chars[3];
NSString *star = @"NO";
byte_chars[0] = '0';
byte_chars[1] = [flags characterAtIndex:1];
byte_chars[2] = 0;
wholeByte = strtol(byte_chars, NULL, 16);
if (wholeByte & 0x01) star = @"YES";
return star;
}
发布于 2018-11-06 16:56:00
至1:
结尾处的0是结尾处的'\0‘(都是零的值),意思是“字符串在这里结束”。你必须把它放在末端才能结束字符串。
开始处的'0‘(字母0)表示strtol()
的八进制值(不是十六进制,即"0x")。但是,正如CRD正确地提到的(见注释),它被传递给strtol()
的第三位arg所取代。因此,到目前为止,您有一个带有0的双字母字符串,第一个字符和标志的十六进制表示形式作为第二个字符。
原因可能是,标志包含一个数字,从'0‘到'f'₁₆/'F'₁₆(0到15₁₀)。
至2:
因为转换产生的值在0的范围内(…)15长值将有其中一个值。您可以将它存储在一个字节中,而不需要一个完整的字节。但是,strtol()
总是返回一个长的。
至3:
是的,它是从包含数字的字符串转换为数字的转换。即字符串"06“将转换为数字6。
发布于 2018-11-08 02:57:10
Amin Negm-Awad解释了代码所做的工作(对八进制有点困惑),但对于回答您的问题:
为什么在我继承的代码中使用strtol方法?
我们只能猜测。
字符串中的第二个字符似乎是用于(最多)4个标志位的十六进制数字,该方法正在测试是否设置了其中最不重要的一个。一个更简单的方法可能是:
- (NSString *)starFromFlags:(NSString *)flags
{
unichar flag = [flags characterAtIndex:1];
if (flag > 127 || !isxdigit(flag)) // check flag is in ASCII range and hex digit
return @"INVALID";
else
return digittoint(flag) & 0x1 ? @"YES" : @"NO"; // check if flag is odd hex
}
isxdigit()
和digittoint()
是C库函数(就像strtol()
一样),在终端中使用man isxdigit
作为文档(除非您使用的Xcode的旧版本包含这些文档,否则苹果将在最新版本中删除文档)。第一个检查字符是否为十六进制数字,第二个检查返回等效的整数。> 127
检查是对字符串中非“ASCII”字符的最小保护。
注意:
NSString
(表示为)为UTF-16代码单元的序列,因此characterAtIndex:
返回unichar
(16位类型),因此是flag
__的类型。但是,此代码不能正确处理任何 unicode字符串。如果您的字符串是"ASCII“,它将工作。
实际上,上面的函数比原始函数进行更多的错误检查,如果您乐于减少错误检查,只需使用:
- (NSString *)starFromFlags:(NSString *)flags
{
return digittoint([flags characterAtIndex:1]) & 0x1 ? @"YES" : @"NO";
}
这将返回@"YES"
当且仅当标志是十六进制数字并设置其LSB时,如果不是十六进制数字或LSB未设置,则返回@"NO"
。这是因为如果digittoint()
的参数不是十六进制数字,它会返回0
。
那么,为什么最初的程序员使用strtol()
呢?也许他们不知道digittoint()
的事。
HTH
https://stackoverflow.com/questions/53182074
复制相似问题