2011-07-14 34 views
7

Tôi có một mã C trong đó tôi đang sử dụng hàm thư viện chuẩn isalpha() trong ctype.h, Đây là trên Visual Studio 2010-Windows. Trong mã dưới đây, nếu char c là '£', cuộc gọi isalpha trả về một sự khẳng định như trong ảnh chụp dưới đây:isalpha() đưa ra một xác nhậ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); 
} 

tôi có thể thấy rằng đây có thể là do 8 bit ASCII không không có nhân vật này.

Vậy làm cách nào để xử lý các ký tự không phải ASCII bên ngoài bảng ASCII?

Điều tôi muốn làm là tìm thấy bất kỳ ký tự không phải chữ cái nào (ngay cả khi ký tự đó không có trong bảng ASCII 8 bit) tôi muốn có thể bỏ qua nó.

+1

Lưu ý rằng ''£'' không phải là ký tự ASCII. Bạn đang pha trộn bối cảnh: kết quả có thể gây ngạc nhiên. – pmg

Trả lời

8

Bạn có thể muốn bỏ giá trị gửi đến isalpha (và các chức năng khác khai báo trong <ctype.h>) để unsigned char

isalpha((unsigned char)value) 

Đó là một trong những (n ot so) vài trường hợp dàn diễn viên thích hợp trong C.


Chỉnh sửa để thêm giải thích.

Theo the standard, nhấn mạnh là của tôi

7,4

1 Tiêu đề <ctype.h> tuyên bố một số chức năng hữu ích để phân loại và lập bản đồ ký tự.Trong mọi trường hợp, đối số là int, giá trị trong đó là thể hiện là unsigned char hoặc bằng giá trị của macro EOF. Nếu đối số có bất kỳ giá trị nào khác, hành vi không xác định.

Dàn diễn viên để đảm bảo unsigned char gọi isalpha() không gọi hành vi undefined.

+0

cảm ơn. char c; c = '£'; isalpha ((unsigned char) (c)); làm việc. Không có xác nhận và isalpha bây giờ trả về '£' là NOT chữ cái. – goldenmean

+0

câu trả lời đúng, IMHO giải thích không đầy đủ ... – Alnitak

+0

@Alnitak: hehehe Tôi đã không thực sự giải thích bất cứ điều gì ... bài chỉnh sửa – pmg

8

Bạn phải vượt qua một int đến isalpha(), không phải là char. Lưu ý nguyên mẫu tiêu chuẩn cho chức năng này:

int isalpha(int c); 

Đi qua một nhân vật đã ký 8-bit sẽ làm cho giá trị được chuyển đổi thành một số nguyên âm, kết quả là một tiêu cực bất hợp pháp bù đắp vào các mảng nội bộ thường được sử dụng bởi isxxxx().

Tuy nhiên bạn phải đảm bảo rằng char của bạn được coi là unsigned khi đúc - bạn có thể không chỉ đơn giản là cast nó trực tiếp đến một int, bởi vì nếu nó là một nhân vật 8-bit kết quả int vẫn sẽ là tiêu cực.

Cách điển hình để đảm bảo tác phẩm này là truyền đến unsigned char và sau đó dựa vào chuyển đổi loại ẩn để chuyển đổi thành một số int.

ví dụ:

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

Tôi không nghĩ vậy. Ngay cả khi tôi đã thử - int c; c = '£'; và truyền nó cho isalpha (c), nó khẳng định. – goldenmean

+1

@goldenmean nếu ký tự mặc định của bạn được ký sẽ vẫn vượt qua số nguyên âm. Điều gì sẽ xảy ra nếu bạn thử 'int c = (unsigned char) '£''? – Alnitak

+0

Như pmg trả lời ở trên, char c; c = '£'; isalpha ((unsigned char) (c)); làm việc. Không có xác nhận và isalpha bây giờ trả về '£' là NOT chữ cái. – goldenmean

2

Bạn có thể được biên dịch sử dụng WCHAR (UNICODE) as type nhân vật, trong trường hợp đó phương pháp isalpha để sử dụng là iswalpha

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

+0

K Cảm ơn. Bây giờ được sử dụng nếu (iswalpha (c)), nó không khẳng định nhưng bây giờ nó vượt qua '£' như một ký tự chữ cái, khi tôi muốn chỉ chữ cái ([a..z]) được suy ra như ký tự chữ cái. – goldenmean

+0

@Anders - bây giờ, trừ khi goldmean thay đổi char của mình thành wchar_t, anh ấy đang trộn char và Unicode, điều này không đúng. – AAT

Các vấn đề liên quan