扯淡的bug之字符数组
2016-02-26 本文已影响67人
7分醉
char与unsigned char
话不多说,先上代码。。。
NSString *inputString = [NSString stringWithFormat:@"dddddddddddd"];//要加密的字符串
NSInputStream *inputStream = [[NSInputStream alloc] initWithData:[inputString dataUsingEncoding:NSUTF8StringEncoding]];
//输出到字符串
static uint8_t buffer[1024];
NSOutputStream *outputStream = [[NSOutputStream alloc] initToBuffer:buffer capacity:1024];
//调用加密接口
[TestAPI encryptData:@"test" inputStream:inputStream outputStream:outputStream block:^(ResultCode code) {
if (SUCCESS == code) {
//成功,从buffer中获取数据
NSString *str = [[NSString alloc] initWithCString:buffer encoding:NSUTF8StringEncoding];
NSLog(@"成功!!!=%@", str);
} else {
//失败
NSLog(@"失败 error=%hu", code);
}
}];
这段代码调用接口方法进行加密,该方法主要有inputStream和outputStream,要加密的内容通过inputStream输入进去,加密结果通过outputStream输出,我们将输出流输出到一个buffer,调用成功后,从buffer中获取加密结果。
思路完全正确,可是运行结束后从buffer中的到的却是null。
其原因就在下面这两行代码上
static uint8_t buffer[1024];
...
NSString *str = [[NSString alloc] initWithCString:buffer encoding:NSUTF8StringEncoding];
其中
typedef unsigned char uint8_t;
- (nullable instancetype)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding;
可以看出,其中的类型不同,一个是unsigned char 类型的 buffer 一个是要求 char 类型的,两者进行强制转换必定会丢失字符。所以导致 str 为 null
对代码更改如下
NSString *inputString = [NSString stringWithFormat:@"dddddddddddd"];//要加密的字符串
NSInputStream *inputStream = [[NSInputStream alloc] initWithData:[inputString dataUsingEncoding:NSUTF8StringEncoding]];
//输出到字符串
static uint8_t buffer[1024];
NSOutputStream *outputStream = [[NSOutputStream alloc] initToBuffer:buffer capacity:1024];
//调用加密接口
[TestAPI encryptData:@"test" inputStream:inputStream outputStream:outputStream block:^(ResultCode code) {
if (SUCCESS == code) {
//成功,从buffer中获取数据
NSData *data = [NSData dataWithBytes:buffer length:strlen(buffer)];
//进行base64编码以方便显示
data = [GTMBase64 encodeData:data];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"成功!!!=%@", str);
} else {
//失败
NSLog(@"失败 error=%hu", code);
}
}];
静态数组的重复利用
- (void)testFunction
{
NSString *inputString = [NSString stringWithFormat:@"dddddddddddd"];//要加密的字符串
NSInputStream *inputStream = [[NSInputStream alloc] initWithData:[inputString dataUsingEncoding:NSUTF8StringEncoding]];
//输出到字符串
static uint8_t buffer[1024];
//memset(buffer, 0, sizeof(uint8_t) * 1024);
NSOutputStream *outputStream = [[NSOutputStream alloc] initToBuffer:buffer capacity:1024];
//调用加密接口
[TestAPI encryptData:@"test" inputStream:inputStream outputStream:outputStream block:^(ResultCode code) {
if (SUCCESS == code) {
//成功,从buffer中获取数据
NSData *data = [NSData dataWithBytes:buffer length:strlen(buffer)];
//进行base64编码以方便显示
data = [GTMBase64 encodeData:data];
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"成功!!!=%@", str);
} else {
//失败
NSLog(@"失败 error=%hu", code);
}
}];
}
将刚才的代码包装在一个方法里其好处是可以实现重复利用
其中的 buffer 为 static 类型,在重复利用的过程中,方法调用结束后第二次使用时 buffer 中还会保留上次的数据。
所以如果在一个方法中有用到 static 来修饰,要明确是否真的需要在方法再次运行时使用之前保存的数据,如果不需要,请在方法开始时对 buffer 进行初始化,例如:
memset(buffer, 0, sizeof(uint8_t) * 1024);
使用 memset 进行内存初始化