2011-07-14 29 views
7

Tengo un código C en el que estoy usando la función de biblioteca estándar isalpha() en ctype.h, esto es en Visual Studio 2010-Windows. En código de abajo, si Char c es '£', la llamada isalpha devuelve una afirmación como se muestra en la figura de abajo:isalpha() dando una aserción

enter image description here

char c='£'; 

if(isalpha(c)) 
{ 
    printf ("character %c is alphabetic\n",c); 

} 
else 
{ 
    printf ("character %c is NOT alphabetic\n",c); 
} 

puedo ver que esto podría ser debido a 8 bits ASCII hace no tiene este personaje

Entonces, ¿cómo manejo esos caracteres no ASCII fuera de la tabla ASCII?

Lo que quiero hacer es si se encuentra un carácter no alfabético (incluso si incluye dicho carácter no en la tabla ASCII de 8 bits) quiero poder descuidarlo.

+1

Tenga en cuenta que ''£'' no es un carácter ASCII. Estás mezclando contextos: el resultado puede ser sorprendente. – pmg

Respuesta

8

es posible que desee emitir el valor enviado a isalpha (y las otras funciones declaradas en <ctype.h>) a unsigned char

isalpha((unsigned char)value) 

es uno de los (n de modo que) pocas ocasiones en las que es apropiado un molde en C.


Editado para agregar una explicación.

Según the standard, el énfasis es mío

7,4

1 La cabecera <ctype.h> declara varias funciones útiles para la clasificación y mapeo caracteres.En todos los casos, el argumento es int, cuyo valor será representable como unsigned char o será igual al valor de macro EOF. Si el argumento tiene algún otro valor, el comportamiento no está definido.

El reparto de unsigned char asegura llamando isalpha() no invoca un comportamiento indefinido.

+0

gracias. char c; c = '£'; isalpha ((char sin signo) (c)); funciona. Ninguna afirmación e isalpha ahora devuelven '£' como NO alfabético. – goldenmean

+0

respuesta correcta, en mi humilde opinión explicación inadecuada ... – Alnitak

+0

@Alnitak: jejeje Realmente no explique nada ... editado – pmg

8

Debe pasar un int a isalpha(), no un char. Tenga en cuenta el prototipo estándar para esta función:

int isalpha(int c); 

Pasando un carácter de 8 bits con hará que el valor a convertir en un entero negativo, lo que resulta en una negativa ilegal desplazamiento en las matrices internas típicamente utilizados por isxxxx().

Sin embargo, usted debe asegurarse de que se trata como charunsigned al lanzar - no se puede simplemente echarlo directamente a un int, porque si es un carácter de 8 bits del resultado int siga siendo negativo.

La forma típica de garantizar que esto funcione es convertirlo a unsigned char, y luego confiar en la conversión de tipo implícito para convertirlo en int.

p. Ej.

char c = '£'; 
int a = isalpha((unsigned char) c); 
+0

No lo creo. Incluso cuando lo intenté - int c; c = '£'; y lo pasó a isalpha (c), afirma. – goldenmean

+1

@goldenmean si sus caracteres predeterminados están firmados y pasarán un número entero negativo. ¿Qué sucede si intenta 'int c = (unsigned char) '£''? – Alnitak

+0

Como pmg respondió anteriormente, char c; c = '£'; isalpha ((char sin signo) (c)); funciona. Ninguna afirmación e isalpha ahora devuelven '£' como NO alfabético. – goldenmean

2

Es posible que se compila utilizando wchar (Unicode) como tipo de carácter, en ese caso el método isalpha a utilizar es iswalpha

http://msdn.microsoft.com/en-us/library/xt82b8z8.aspx

+0

K Gracias. Ahora se usa if (iswalpha (c)), no afirma, pero ahora pasa '£' como un carácter alfabético, cuando quiero que solo letras ([a..z]) se deduzcan como caracteres alfabéticos. – goldenmean

+0

@Anders - ahora, a menos que goldenmean cambie su char a wchar_t, está mezclando char y Unicode, lo que no está bien seguramente. – AAT