strcasecmp
C 에서 함수 를 다시 구현하려고하는데 비교 과정에서 불일치하는 것으로 나타났습니다.
에서 man strcmp
strcmp () 함수는 두 문자열 s1과 s2를 비교합니다. 로케일은 고려되지 않습니다 (로케일 인식 비교는 strcoll (3) 참조). s1이 각각 s2보다 작거나 일치하거나 s2보다 크면 0보다 작거나 같거나 0보다 큰 정수를 리턴합니다.
에서 man strcasecmp
strcasecmp () 함수는 문자열의 경우를 무시하고 문자열 s1 및 s2를 바이트 단위로 비교합니다. s1이 각각 s2보다 작거나 일치하거나 s2보다 크면 0보다 작거나 같거나 0보다 큰 정수를 리턴합니다.
int strcmp(const char *s1, const char *s2);
int strcasecmp(const char *s1, const char *s2);
이 정보가 주어지면 다음 코드의 결과를 이해하지 못합니다.
#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;
}
출력 :
-1 # "A" is less than "_"
1 # "a" is more than "_"
2 # "A" is more than "_" with strcasecmp ???
2 # "a" is more than "_" with strcasecmp
현재 문자 s1
가 문자이면 현재 문자 가 문자 인지 여부에 관계없이 항상 소문자로 변환됩니다 s2
.
누군가이 행동을 설명 할 수 있습니까? 첫 번째 줄과 세 번째 줄이 동일하지 않아야합니까?
미리 감사드립니다!
추신 :
저는 gcc 9.2.0
Manjaro를 사용 하고 있습니다.
또한 -fno-builtin
플래그로 컴파일 하면 대신 얻을 수 있습니다.
-30
2
2
2
프로그램이 gcc의 최적화 된 기능을 사용하지 않기 때문이지만 질문은 남아 있습니다.
답변
동작이 정확합니다.
당 는 POSIX의 str\[n\]casecmp()
사양 :
LC_CTYPE
사용되는 로케일 의 카테고리가 POSIX 로케일의 것이라면,이 함수는 문자열이 소문자로 변환 된 다음 바이트 비교가 수행 된 것처럼 작동합니다. 그렇지 않으면 결과가 지정되지 않습니다.
그것도의 일부입니다 NOTES의 리눅스 man 페이지의 섹션 :
POSIX.1-2008 표준은 다음 기능을 말합니다.
사용되는 로케일의 LC_CTYPE 범주가 POSIX 로케일에서 온 경우,이 함수는 문자열이 소문자로 변환 된 후 바이트 비교가 수행 된 것처럼 작동합니다. 그렇지 않으면 결과가 지정되지 않습니다.
왜?
@HansOlsson이 그의 답변에서 지적했듯이 문자 만 대소 문자를 구분하지 않고 비교하면 다른 모든 비교에서 “자연스러운”결과를 얻을 수 있으므로 strcmp()
정렬이 어려워 집니다 .
경우 'A' == 'a'
(대소 문자를 구분하지 않는 비교의 정의는) 다음 '_' > 'A'
과 '_' < 'a'
(ASCII 문자 세트의 “자연”결과는) 모두 사실이 될 수 없습니다.
답변
strcasecmp에 대한 다른 링크 http://man7.org/linux/man-pages/man3/strcasecmp.3p.html 에 따르면 소문자로 변환하는 것이 올바른 동작이라고합니다 (적어도 POSIX 로켈에서).
그 동작의 이유는 strcasecmp를 사용하여 문자열 배열을 정렬하면 합리적인 결과를 얻는 것이 필요하기 때문입니다.
그렇지 않으면 예를 들어 qsort를 사용하여 “A”, “C”, “_”, “b”를 정렬하려고하면 결과는 비교 순서에 따라 달라집니다.
답변
s1의 현재 문자가 문자이면 s2의 현재 문자가 문자인지 여부에 관계없이 항상 소문자로 변환됩니다.
맞습니다. 그리고 strcasecmp()
함수 가해야 할 일입니다! 이 POSIX
기능은 C
표준의 일부가 아니라 ” 공개 그룹 기본 사양, 문제 6 “의 기능입니다.
POSIX 로케일에서 strcasecmp () 및 strncasecmp ()는 문자열이 소문자로 변환 된 후 바이트 비교가 수행 된 것처럼 동작합니다. 다른 로케일에서는 결과가 지정되지 않습니다.
또한이 동작은 _stricmp()
Visual Studio / MSCV에서 사용되는 함수와 도 관련이 있습니다 .
_stricmp 함수는 일반적으로 각 문자를 소문자로 변환 한 후 string1과 string2를 비교하고 관계를 나타내는 값을 반환합니다.
답변
대한 ASCII 진수 코드 A
입니다 65
에 대한 _
것입니다 95
및 위해 a
이다 97
, 그래서 strcmp()
할 가정 해 무엇을하고있어. 사 전적으로 말하기 _
는 다음보다 작고 a
큽니다 A
.
strcasecmp()
* A
로 간주 되며 출력이 크기보다 크므로 정확합니다.a
a
_
* POSIX.1-2008 표준에 따르면 이러한 함수 (strcasecmp () 및 strncasecmp ())에 대해 설명합니다.
사용되는 로케일의 LC_CTYPE 범주가 POSIX 로케일에서 온 경우,이 함수는 문자열이 소문자로 변환 된 후 바이트 비교가 수행 된 것처럼 작동합니다. 그렇지 않으면 결과가 지정되지 않습니다.
답변
