1. 문자열 비교 함수
#include <string.h>
int strcmp(const char * s1, const char * s2);
int strncmp(const char * s1, const char * s2, size_t n);
문자열의 내용이 같으면 0, 아니면 0이 아닌 값을 반환한다.
strncmp 함수는 n 바이트만 비교한다.
s1 이 더 크면 양수가, s2 가 더 크면 음수가, s1 과 s2 의 모든 문자가 같으면 0이 반환된다.
여기서 크고 작음은 아스키 코드 값을 기준으로 결정된다.
그런데 문자열을 비교하는 데 굳이 함수를 써야 하는 걸까?
물론 써야 하니까 소개하는 것이다. 하지만 이유는 알아야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <stdio.h>
int main()
{
char str1[] = "Happy Ending";
char str2[] = "Happy Ending";
if (str1 == str2)
{
puts("equal");
}
else
{
puts("different");
}
return 0;
}
|
cs |
8행에서는 정말 문자열을 비교하고 있을까?
배열의 이름은 배열의 시작주소다. 따라서 8행에서 비교하는 것은 배열의 시작주소다.
다시 말해 str1 에서 H 의 주소와 str2 에서 H 의 주소를 비교한다는 것이다.
str1 의 H 와 str2 의 H 를 비교하는 것이 아니다.
그래서 문자열을 비교하려면 strcmp 함수를 써야 하는 것이다.
strcmp 함수는 각 문자열의 첫 글자부터 마지막 글자, 즉 널 문자까지 하나씩 비교한다.
구체적인 비교 방식은 다음과 같다.
① "ABCDE", "ABCDE"
첫 번째 문자부터 널 문자까지 두 문자열의 모든 내용이 같다.
따라서 A부터 널 문자까지 비교를 진행한 후 0을 반환한다.
② "ABDDE", "ABCCE"
첫 번째 문자부터 두 번째 문자까지는 모두 같지만, 세 번째 문자는 다르다.
따라서 세 번째 문자까지 비교를 진행한 후 비교를 중단한다. 그리고 양수를 반환한다.
strcmp 함수는 두 문자가 다르면 바로 비교를 중단하고 값을 반환하므로, 그 뒤 문자의 동일 여부는 의미가 없다. 그러니까 여기서는 세 번째 문자가 다르므로, 네 번째 문자가 D와 C로 다른 것은 의미가 없다는 것이다.
③ "ABCD", "ABCDE"
첫 번째 문자부터 네 번째 문자, 그러니까 A부터 D까지는 같다.
그런데 다섯 번째가 문제다. "ABCD"는 네 글자고, "ABCDE"는 다섯 글자이기 때문이다.
이 경우 첫 번째 문자열의 널 문자와 두 번째 문자열의 E가 비교되므로 여기까지만 비교한 후 음수를 반환한다.
strcmp 함수는 두 문자열이 같으면 0, 첫 번째 문자열이 더 크면 양수, 두 번째 문자열이 더 크면 음수를 반환한다. 다시 말해 같으면 0, 아니면 0이 아닌 값을 반환한다.
일반적으로 문자열의 동일 여부를 검사하는 용도로 사용되기 때문에, 언제 양수가 반환되고 언제 음수가 반환되는지는 중요한 사항이 아니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#include <stdio.h>
#include <string.h>
int main()
{
char str1[10] = "ABCDDFGH";
char str2[10] = "ABCDEFGH";
if (!strncmp(str1, str2, 4))
{
puts("앞의 네 글자는 같습니다.");
if (!strcmp(str1, str2))
{
puts("나머지도 같네요");
}
else
{
puts("나머지는 다르네요");
}
}
else
{
puts("두 문자열은 다릅니다.");
}
return 0;
}
|
cs |
다음과 같이 간단한 인증을 구현할 수도 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#include <stdio.h>
#include <string.h>
int main()
{
char id[20];
char pw[20];
char user_id[20] = "id";
char user_pw[20] = "password";
fputs("아이디 입력: ", stdout);
fgets(id, sizeof(id), stdin);
fputs("비밀번호 입력: ", stdout);
fgets(pw, sizeof(pw), stdin);
if (!strcmp(id, user_id))
{
if (!strcmp(pw, user_pw))
{
puts("로그인 되었습니다.");
}
else
{
puts("패스워드를 확인하세요.");
}
}
else
{
puts("아이디를 확인하세요.");
}
return 0;
}
|
cs |
2. strcmp 함수의 반환값
앞에서는 양수, 음수 또는 0이 아닌 값이라고 뭉뚱그려 말했지만, 엄밀히 말하면 두 문자의 아스키 코드 값의 차이다.
물론 이것은 컴파일러에 따라 다르다. 컴파일러에 따라 1, 0, -1이 출력되기도 한다.
Visual Studio 2017이 그 예다.
gcc라는 컴파일러의 경우 매개변수에 문자 배열을 전달해 비교하면 아스키 코드 값의 차이가 반환되고, 큰 따옴표를 써서 문자열 자체를 전달해 비교하면 1, 0, -1이 반환된다.
'Programming > C' 카테고리의 다른 글
문자열을 숫자로 변환하는 함수 (0) | 2019.05.18 |
---|---|
sprinf, sscanf 함수 (0) | 2019.05.18 |
문자열 길이 측정, 복사, 연결 함수 (0) | 2019.05.13 |
문자열 입출력 함수 (0) | 2019.05.07 |
문자 입출력 함수 (0) | 2019.05.05 |