NSCharacter Set usa int's pero necesito short no asignado?

Estoy usando MWFeedParser para agregar un feed a mi aplicación. Ahora el marco pasa la date y yo tengo algunas advertencias principalmente debido a un tipo de código anterior.

Ahora quedan 4 advertencias que son iguales y, técnicamente, puedo corregirlas y eliminarlas para que las advertencias no estén, pero luego me quedo con que la aplicación no funcione correctamente.

El código concerniente es:

// Character sets NSCharacterSet *stopCharacters = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@"< \t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]]; 

Ahora la parte que es la advertencia es:

 \t\n\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]]; 

La advertencia es:

El formatting especifica el tipo 'unsigned short' pero el argumento tiene el tipo 'int'

Entonces me cambié a:

 \t\n\r%i%i%i%i", 0x0085, 0x000C, 0x2028, 0x2029]]; 

que de hecho eliminó las advertencias y me dio el código perfecto 🙂 (sin advertencias ni errores)

Cuando ejecuté la aplicación, no analizó la date y no pudo abrir el enlace. No estoy seguro de si esto es C cosa, pero ahora está definitivamente fuera de mi campo de conocimiento. ¿Hay alguien que pueda ayudarme que pueda solucionar este problema, y ​​todavía tenerlo funcionando en la aplicación?

Gracias de antemano:-)

EDITAR

  - (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]; 

}

Esto es un desastre total.

La razón por la que esto es un desastre total se debe a que se está ejecutando un error de compilation y una limitación arbitraria en la especificación C.

Desplácese hasta la parte inferior para ver la solución.

Advertencia del comstackdor

El formatting especifica el tipo 'unsigned short' pero el argumento tiene el tipo 'int'

Mi conclusión es que este es un error del comstackdor en Clang. Definitivamente, es seguro ignorar esta advertencia, ya que los arguments (unsigned short) siempre se promocionan a (int) antes de que se pasen a las funciones de vararg de todos modos. Esto es todo lo que está en el estándar C (y también se aplica al Objetivo 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. 

El problema aquí es que ninguno de los comstackdores se ve lo suficientemente profundo.

Recuerde, en realidad es imposible pasar un short a printf() , ya que debe promocionarse a int . GCC nunca da una advertencia de constantes, Clang ignora el hecho de que está pasando una constante y siempre da una advertencia porque el tipo es incorrecto. Ambas opciones son incorrectas.

Sospecho que nadie lo ha notado porque, ¿por qué ibas a pasar una expresión constante a printf() todos modos?

En el corto ploop, puede usar el siguiente hack:

 #pragma GCC diagnostic ignonetworking "-Wformat" 

Nombres de carácter universales

Puede usar la notación \uXXXX . Excepto que no puedes, porque el comstackdor no te permitirá usar U+0085 esta manera. ¿Por qué? Vea § 6.4.3 de C99:

Un nombre de carácter universal no debe especificar un carácter cuyo identificador corto sea menor a 00A0 no sea 0024 ( $ ), 0040 ( @ ) o 0060 ( ' ), ni uno en el range D800 a DFFF inclusive.

Esto descarta \u0085 .

Hay una propuesta para corregir esta parte de la especificación.

La solución

¿De verdad quieres una string constante, no? Utilizar esta:

 [NSCharacterSet characterSetWithCharactersInString: @"\t\n\r\xc2\x85\x0c\u2028\u2029"] 

Esto se basa en el hecho de que la encoding fuente es UTF-8. No te preocupes, eso no va a cambiar en el corto ploop.

El \xc2\x85 en la cadena es la encoding UTF-8 de U+0085 . La aparición de 85 en ambos es una coincidencia.

El problema es que 0x0085 , etc son literalmente integers. Entonces no coinciden con el especificador de formatting %C , que espera un unichar , que es un corto sin firmar.

No hay una forma directa de especificar un breve literal en C y no conozco ninguna extensión de Objective-C. Pero puedes usar un enfoque de fuerza bruta:

 NSCharacterSet *stopCharacters = [NSCharacterSet characterSetWithCharactersInString: [NSString stringWithFormat:@"< \t\n\r%C%C%C%C", (unichar)0x0085, (unichar)0x000C, (unichar)0x2028, (unichar)0x2029]]; 

No necesitas stringWithFormat, puedes incrustar los caracteres unicode directamente en una cadena usando \ u escape. Por ejemplo \ u0085.