Tôi đang cố gắng thực hiện lại strcasecmp
chức năng trong C và tôi nhận thấy những gì dường như không nhất quán trong quá trình so sánh.
Từ man strcmp
Hàm strcmp () so sánh hai chuỗi s1 và s2. Bản địa không được tính đến (để so sánh nhận biết bản địa, xem strcoll (3)). Nó trả về một số nguyên nhỏ hơn, bằng hoặc lớn hơn 0 nếu tìm thấy s1 tương ứng nhỏ hơn, để khớp hoặc lớn hơn s2.
Từ man strcasecmp
Hàm strcasecmp () thực hiện so sánh từng byte của chuỗi s1 và s2, bỏ qua trường hợp của các ký tự. Nó trả về một số nguyên nhỏ hơn, bằng hoặc lớn hơn 0 nếu tìm thấy s1 tương ứng nhỏ hơn, để khớp hoặc lớn hơn s2.
int strcmp(const char *s1, const char *s2);
int strcasecmp(const char *s1, const char *s2);
Cho, thông tin này, tôi không hiểu kết quả của đoạn mã sau:
#include <stdio.h>
#include <string.h>
int main()
{
// ASCII values
// 'A' = 65
// '_' = 95
// 'a' = 97
printf("%i\n", strcmp("A", "_"));
printf("%i\n", strcmp("a", "_"));
printf("%i\n", strcasecmp("A", "_"));
printf("%i\n", strcasecmp("a", "_"));
return 0;
}
Ouput:
-1 # "A" is less than "_"
1 # "a" is more than "_"
2 # "A" is more than "_" with strcasecmp ???
2 # "a" is more than "_" with strcasecmp
Dường như, nếu ký tự hiện tại trong s1
một chữ cái, nó luôn được chuyển đổi thành chữ thường, bất kể ký tự hiện tại trong đó s2
có phải là một chữ cái hay không.
Ai đó có thể giải thích hành vi này? Không phải dòng đầu tiên và thứ ba là giống hệt nhau?
Cảm ơn bạn trước!
PS:
Tôi đang sử dụng gcc 9.2.0
trên Manjaro.
Ngoài ra, khi tôi biên dịch với -fno-builtin
cờ tôi nhận được thay thế:
-30
2
2
2
Tôi đoán đó là vì chương trình không sử dụng các chức năng tối ưu hóa của gcc, nhưng câu hỏi vẫn còn.
strcasecmp
bạn đang giới thiệu là không chính xác. Thêm chi tiết trong các câu trả lời nâng cao.
A < _ && a > _ && A == a
sẽ gây ra rất nhiều vấn đề.
unsigned char
. C17 / 18 "Xử lý chuỗi <string.h>" -> "Đối với tất cả các chức năng trong phần này, mỗi ký tự sẽ được hiểu như thể nó có kiểu unsigned char
". Điều này tạo ra sự khác biệt khi char
các giá trị nằm ngoài phạm vi ASCII 0-127.
printf("%i\n", strcasecmp("a", "_"));
Điều này có lẽ sẽ có kết quả tương tự nhưprintf("%i\n", strcasecmp("A", "_"));
Nhưng điều đó có nghĩa là một trong hai cuộc gọi không phân biệt chữ hoa chữ thường này sẽ không đồng ý với đối tác phân biệt chữ hoa chữ thường.