NSCharacter集使用int的,但我需要未分配的短?
我正在使用MWFeedParser添加一个饲料到我的应用程序。 现在框架通过date和我有几个警告,主要是由于旧的代码types。
现在有四个警告都是一样的,技术上我可以修复它们,并将它们删除,以便警告消失,但是随后应用程序无法正常工作。
有关的代码是:
// Character sets NSCharacterSet *stopCharacters = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@"< \t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
现在警告的是:
\t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
警告是:
格式指定types'unsigned short',但参数的types为'int'
所以我改成:
\t\n\r%i%i%i%i", 0x0085, 0x000C, 0x2028, 0x2029]];
这确实删除了警告,并给了我完美的代码:-)(没有警告或错误)
当我然后运行应用程序它不parsing的date,它无法打开链接。 我不确定这个a是否是C的东西,但现在它肯定在我的知识领域之外。 有没有人可以帮助我,可以解决这个问题,并仍然在应用程序中工作?
先谢谢你:-)
编辑
- (NSString *)stringByConvertingHTMLToPlainText { // Pool NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Character sets NSCharacterSet *stopCharacters = [NSCharacterSet characterSetWithCharactersInString:@"< \t\n\r\x0085\x000C\u2028\u2029"]; NSCharacterSet *newLineAndWhitespaceCharacters = [NSCharacterSet characterSetWithCharactersInString:@"< \t\n\r\205\014\u2028\u2029"]; NSCharacterSet *tagNameCharacters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"]; // Scan and find all tags NSMutableString *result = [[NSMutableString alloc] initWithCapacity:self.length]; NSScanner *scanner = [[NSScanner alloc] initWithString:self]; [scanner setCharactersToBeSkipped:nil]; [scanner setCaseSensitive:YES]; NSString *str = nil, *tagName = nil; BOOL dontReplaceTagWithSpace = NO; do { // Scan up to the start of a tag or whitespace if ([scanner scanUpToCharactersFromSet:stopCharacters intoString:&str]) { [result appendString:str]; str = nil; // reset } // Check if we've stopped at a tag/comment or whitespace if ([scanner scanString:@"<" intoString:NULL]) { // Stopped at a comment or tag if ([scanner scanString:@"!--" intoString:NULL]) { // Comment [scanner scanUpToString:@"-->" intoString:NULL]; [scanner scanString:@"-->" intoString:NULL]; } else { // Tag - remove and replace with space unless it's // a closing inline tag then dont replace with a space if ([scanner scanString:@"/" intoString:NULL]) { // Closing tag - replace with space unless it's inline tagName = nil; dontReplaceTagWithSpace = NO; if ([scanner scanCharactersFromSet:tagNameCharacters intoString:&tagName]) { tagName = [tagName lowercaseString]; dontReplaceTagWithSpace = ([tagName isEqualToString:@"a"] || [tagName isEqualToString:@"b"] || [tagName isEqualToString:@"i"] || [tagName isEqualToString:@"q"] || [tagName isEqualToString:@"span"] || [tagName isEqualToString:@"em"] || [tagName isEqualToString:@"strong"] || [tagName isEqualToString:@"cite"] || [tagName isEqualToString:@"abbr"] || [tagName isEqualToString:@"acronym"] || [tagName isEqualToString:@"label"]); } // Replace tag with string unless it was an inline if (!dontReplaceTagWithSpace && result.length > 0 && ![scanner isAtEnd]) [result appendString:@" "]; } // Scan past tag [scanner scanUpToString:@">" intoString:NULL]; [scanner scanString:@">" intoString:NULL]; } } else { // Stopped at whitespace - replace all whitespace and newlines with a space if ([scanner scanCharactersFromSet:newLineAndWhitespaceCharacters intoString:NULL]) { if (result.length > 0 && ![scanner isAtEnd]) [result appendString:@" "]; // Dont append space to beginning or end of result } } } while (![scanner isAtEnd]); // Cleanup [scanner release]; // Decode HTML entities and return NSString *retString = [[result stringByDecodingHTMLEntities] retain]; [result release]; // Drain [pool drain]; // Return return [retString autorelease];
}
这是一团糟
这是一个混乱的原因是因为你遇到了一个编译器错误和 C规范的任意限制。
滚动到底部进行修复。
编译器警告
格式指定types'unsigned short',但参数的types为'int'
我的结论是,这是一个在铿锵编译器错误。 忽略这个警告是绝对安全的,因为(unsigned short)
参数总是被提升为(int)
然后它们被传递给可变参数函数。 这是所有在C标准中的东西(它也适用于Objective C)。
printf("%hd", 1); // Clang generates warning. GCC does not. // Clang is wrong, GCC is right. printf("%hd", 1 << 16); // Clang generates warning. GCC does not. // Clang is right, GCC is wrong.
这里的问题是编译器看起来不够深刻。
请记住,实际上不可能将一个short
传递给printf()
,因为它必须被提升为int
。 海湾合作委员会从来没有给出常量的警告,克朗忽略了这样的事实,你传递一个常数,并总是给出警告,因为types是错误的。 两种select都是错误的。
我怀疑没有人注意到,因为 – 为什么你会传递一个常量expression式printf()
呢?
在短期内,你可以使用下面的黑客:
#pragma GCC diagnostic ignored "-Wformat"
通用字符名称
您可以使用\uXXXX
表示法。 除了你不能,因为编译器不会让你这样使用U+0085
。 为什么? 参见C99的第6.4.3节:
通用字符名称不能指定
0024
($
),0040
(@
)或0060
('
)以外的短标识符小于00A0
的字符,也不能指定D800
到DFFF
范围内的DFFF
。
这就排除了\u0085
。
有一个build议来解决这部分规范。
修复
你真的想要一个固定的string,不是吗? 用这个:
[NSCharacterSet characterSetWithCharactersInString: @"\t\n\r\xc2\x85\x0c\u2028\u2029"]
这依赖于源编码是UTF-8的事实。 别担心,这不会很快改变。
string中的\xc2\x85
是U+0085
的UTF-8编码。 两者的出现都是巧合。
问题是, 0x0085
等是字面整数。 因此,它们不匹配%C
格式说明符,它需要unichar
,这是一个无符号短格式。
没有直接的方法来指定C中的文字短小,我不知道任何Objective-C扩展。 但是你可以使用暴力方法:
NSCharacterSet *stopCharacters = [NSCharacterSet characterSetWithCharactersInString: [NSString stringWithFormat:@"< \t\n\r%C%C%C%C", (unichar)0x0085, (unichar)0x000C, (unichar)0x2028, (unichar)0x2029]];
你不需要stringWithFormat,你可以使用\ u转义符将unicode字符直接embedded到string中。 例如\ u0085。