2011-07-14 4 views
7

Mam kod C, w którym używam standardowej funkcji biblioteki isalpha() w ctype.h, To jest na Visual Studio 2010-Windows. W poniższym kodzie, jeśli char c jest „£”, rozmowa isalpha zwraca twierdzenie, jak pokazano w poniższej migawka:isalpha() podając twierdzenie

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); 
} 

widzę, że może to być spowodowane 8 bit ASCII robi nie masz tej postaci.

Jak obsługiwać takie znaki spoza zestawu ASCII poza tabelą ASCII?

Co chcę zrobić, jeśli zostanie znaleziony dowolny znak niealfabetyczny (nawet jeśli zawiera taki znak, nie w 8-bitowej tablicy ASCII), chcę go zignorować.

+1

Zauważ, że '' £ ''nie jest znakiem ASCII. Łączycie konteksty: wynik może być zaskakujący. – pmg

Odpowiedz

8

Możesz rzucić wartość wysłana do isalpha (i inne funkcje zadeklarowane w <ctype.h>) do unsigned char

isalpha((unsigned char)value) 

jest to jeden z (n ot) kilka razy, w których odlew jest odpowiedni w C.


Edytowane w celu dodania wyjaśnienia.

Według the standard nacisk jest kopalnia

7,4

1 Nagłówek <ctype.h> deklaruje kilka funkcji przydatnych dla klasyfikowania i mapowanie znaków.We wszystkich przypadkach argumentem jest int, którego wartość powinna być równa reprezentowana jako unsigned char lub równa wartości makra EOF. Jeśli argument ma dowolną inną wartość, zachowanie jest niezdefiniowane.

Obsada do unsigned char gwarantuje wywołanie isalpha() nie wywołać zachowanie niezdefiniowane.

+0

dzięki. char c; c = "£"; isalpha ((unsigned char) (c)); działa. Brak asercji i isalpha zwraca teraz "£" jako NIE alfabetyczny. – goldenmean

+0

prawidłowa odpowiedź, IMHO niewystarczające wyjaśnienie ... – Alnitak

+0

@Alnitak: hehehe tak naprawdę nie wyjaśniłem niczego ... post edytowany – pmg

8

Musisz przekazać int do isalpha(), a nie char. Uwaga standardowego prototyp dla tej funkcji:

int isalpha(int c); 

Przechodząc 8-bitową postać spowoduje wartość być przekształcony w dodatnią liczbę całkowitą, co powoduje przesunięcie do nielegalnego ujemny wewnętrznych tablic zwykle stosowanych isxxxx().

jednak należy upewnić się, że char jest traktowany jako unsigned podczas rzucania - nie można po prostu rzucić go bezpośrednio do int, bo jeśli jest to znak 8-bitowy otrzymany int nadal będzie ujemny.

Typowym sposobem zapewnienia tego jest przesłanie go do unsigned char, a następnie poleganie na niejawnej konwersji typu w celu przekonwertowania go na int.

np.

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

Nie sądzę. Nawet kiedy próbowałem - int c; c = "£"; i przekazał ją do aalfa (c), zapewnia. – goldenmean

+1

@goldenmean, jeśli podpisujesz domyślne znaki, które będą nadal przekazywać ujemną liczbę całkowitą. Co stanie się, jeśli spróbujesz 'int c = (unsigned char) '£''? – Alnitak

+0

Jak odpowiedział pmg powyżej, char c; c = "£"; isalpha ((unsigned char) (c)); działa. Brak asercji i isalpha zwraca teraz "£" jako NIE alfabetyczny. – goldenmean

2

może być kompilacji używając WCHAR (Unicode) jako typ postaci, w tym przypadku metoda isalpha do wykorzystania jest iswalpha

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

+0

K Dzięki. Teraz używane, jeśli (iswalpha (c)), nie potwierdza, ale teraz przekazuje "£" jako znak alfabetyczny, kiedy chcę, aby tylko litery ([a..z]) były wyprowadzane jako znaki alfabetyczne. – goldenmean

+0

@Anders - teraz, chyba że goldenmean zmieni jego znak na wchar_t, miesza on char i Unicode, co nie jest oczywiście pewne. – AAT