34. 문자열 길이/내용 비교
1. 키워드
strlen
(String Length)strcmp
(String Compare)
2. 문자열의 길이를 구하고 비교하기
- 이번에는 문자열의 길이를 구하는 방법, 두 문자열이 같은지 비교하는 방법을 알아보자.
3. 문자열 길이 구하기
- 문자열은 문자가 여러 개 모여있으므로 길이가 있다.
string.h
헤더 파일에 선언되어 있는strlen
함수를 사용하면 문자열의 길이를 구할 수 있다.
#include <stdio.h>
#include <string.h> // strlen 함수가 선언된 헤더 파일
int main()
{
char *s1 = "Hello"; // 포인터에 문자열 "Hello"의 주소 저장
char s2[10] = "Hello"; // 크기가 10인 char 타입 배열을 선언하고 문자열 할당
printf("%d\n", strlen(s1)); // strlen 함수로 문자열의 길이를 구함
printf("%d\n", strlen(s2)); // strlen 함수로 문자열의 길이를 구함
return 0;
}
// 5
// 5
strlen(s1)
과 같이strlen
함수에 문자열 포인터를 넣으면 문자열의 길이가 반환된다.- 여기서는
"Hello"
가 다섯 글자이므로5
가 반환된다. - 즉,
strlen
으로 문자열 길이를 구할 때는 순순하게 문자열의 길이만 구하며NULL
부분은 포함하지 않는다. strlen(s2)
와 같이strlen
함수에 문자열이 들어있는 배열을 넣으면 안에 들어있는 문자열의 길이가 반환된다.- 마찬가지로 순수하게 문자열의 길이만 구하며
NULL
부분은 포함하지 않는다. - 특히 배열의 크기와는 상관없이 문자열의 길이만 구한다.
s2[10]
이면 배열 크기가10
이라strlen(s2)
는10
이 될 것 같지만 실제로는 안에 들어있는"Hello"
가 다섯 글자이므로5
가 반환된다.
4. 문자열 비교하기
string.h
헤더 파일에 선언되어 있는strcmp
함수를 사용하면 두 문자열이 같은지 비교할 수 있다.
#include <stdio.h>
#include <string.h> // strcmp 함수가 선언된 헤더 파일
int main()
{
char s1[10] = "Hello";
char *s2 = "Hello";
int ret = strcmp(s1, s2); // 두 문자열이 같은지 문자열 비교
printf("%d\n", ret); // 두 문자열이 같으면 0
return 0;
}
// 0
strcmp(s1, s2);
와 같이strcmp
함수에 비교할 문자열을 넣어주면 결과를 정수로 반환한다.- 문자열을 비교할 때는 대소문자를 구분한다.
1] -1
- ASCII 코드 기준으로 문자열2(
s2
)가 클 때
2] 0
- ASCII 코드 기준으로 두 문자열이 같을 때
3] 1
- ASCII 코드 기준으로 문자열1(
s1
)이 클 때
- 여기서는
s1
과s2
의 문자열이 같으므로0
을 반환한다. - 그리고 배열 형태의 문자열, 문자열 포인터 등 문자열의 저장 방식은 문자열 비교에 영향을 주지 않는다.
- 이때 문자열 포인터에
NULL
이 들어가 있다면 에러가 발생한다.
strcmp
함수는 문자열에서 첫 번째 문자부터 차례대로 비교하며 비교 기준은 각 문자의 ASCII 코드이다.
#include <stdio.h>
#include <string.h> // strcmp 함수가 선언된 헤더 파일
int main()
{
// "aaa"는 ASCII 코드로 97 97 97
// "aab"는 ASCII 코드로 97 97 98
// "aac"는 ASCII 코드로 97 97 99
printf("%d\n", strcmp("aaa", "aaa")); // "aaa"와 "aaa"는 같으므로 0
printf("%d\n", strcmp("aab", "aaa")); // "aab"와 "aaa" 중에서 "aab"가 크므로 1
printf("%d\n", strcmp("aab", "aac")); // "aab"와 "aac" 중에서 "aac"가 크므로 -1
return 0;
}
// 0
// 1
// -1
"aab"
는 ASCII 코드로97 97 98
이고,"aaa"
는97 97 97
이라서"aab"
가 크다.- 즉, 문자열1이 크므로
1
을 반환한다. - 그리고
"aab"
는97 97 98
이고,"aac"
는97 97 99
라서"aac"
가 크다. - 여기서는 문자열2가 크므로
-1
을 반환한다. - 쉽게 생각해서 앞에 것이 크면
1
, 뒤에 것이 크면-1
이다.
- 이번에는 사용자가 입력한 두 문자열을 비교해 보자.
#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h> // strcmp 함수가 선언된 헤더 파일
int main()
{
char s1[20];
char s2[20];
printf("문자열 두 개를 입력하세요: ");
scanf("%s %s", s1, s2);
int ret = strcmp(s1, s2); // 입력된 문자열 비교
switch (ret)
{
case 0:
printf("두 문자열이 같음\n");
break;
case 1:
printf("%s보다 %s가 큼\n", s2, s1);
break;
case 2:
printf("%s보다 %s가 큼\n", s1, s2);
break;
}
return 0;
}
// 문자열 두 개를 입력하세요: hello world (입력)
// hello보다 world가 큼
scanf
함수를 사용하여 공백으로 구분된 문자열을 입력받은 뒤 배열 두 개에 저장했다.- 그리고
strcmp
함수로 문자열을 비교한 뒤 반환값은switch
분기문으로 판단해 봤다.
- 한 가지 주의할 점이 있는데
strcmp
함수는 OS에 따라서 동작 방식이 조금 다르다는 점이다. - Windows(Visual Studio)에서는 문자열이 다르면
1
과-1
을 반환하지만 리눅스와 OSX에서는 ASCII 코드값의 차이를 반환한다. - 그러므로 리눅스와 OSX에서
strcmp
의 반환값을 판단할 때는switch
분기문 대신if
조건문을 사용해야 한다.
#define _CRT_SECURE_NO_WARNINGS // scanf 보안 경고로 인한 컴파일 에러 방지
#include <stdio.h>
#include <string.h> // strcmp 함수가 선언된 헤더 파일
int main()
{
char s1[20];
char s2[20];
printf("문자열 두 개를 입력하세요: ");
scanf("%s %s", s1, s2);
int ret = strcmp(s1, s2); // 입력된 문자열 비교
printf("반환값: %d\n", ret);
// 리눅스와 OSX에서는 ASCII 코드값의 차이를 반환하므로
// if 조건문으로 판단
if (ret == 0)
{
printf("두 문자열이 같음\n");
}
else if (ret > 0) // 양수일 때
{
printf("%s보다 %s가 큼\n", s2, s1);
}
else if (ret < 0) // 음수일 때
{
printf("%s보다 %s가 큼\n", s1, s2);
}
return 0;
}
// 문자열 두 개를 입력하세요: aaf aaa (입력)
// 반환값: 5
// aaa보다 aaf가 큼
- 다음은 리눅스와 OSX에서
strcmp
함수의 반환값 규칙이다.
1] 문자열1의 ASCII 코드값에서 문자열2의 ASCII 코드값을 뺏을 때 양수
가 나오면 문자열1이 크고, 음수
가 나오면 문자열2가 큼
2] ASCII 코드 기준으로 두 문자열이 같으면 0
"aaf"
와"aaa"
를 입력했을 때 반환값이5
가 나왔다.- 즉,
'f'
는102
,'a'
는97
이고102 - 97
은5
이기 때문이다. - 반환값을 판단할 때도
if
,else if
에 조건식을 지정하여0
인지양수
인지,음수
인지 판단하면 된다.