본문 바로가기
CodingTest/백준

[c++] 백준 - 2920번: 음계 | char배열과 String클래스를 사용한 문자열비교

by Daybreak21 2023. 4. 12.

2920번: 음계 (acmicpc.net)

 

2920번: 음계

다장조는 c d e f g a b C, 총 8개 음으로 이루어져있다. 이 문제에서 8개 음은 다음과 같이 숫자로 바꾸어 표현한다. c는 1로, d는 2로, ..., C를 8로 바꾼다. 1부터 8까지 차례대로 연주한다면 ascending, 8

www.acmicpc.net

 

 

※ 정답코드

#include <iostream>
using namespace std;

int main() {
	char array[9];
	for (int i = 0; i < 8; i++) {
		cin >> array[i];
	}
	array[8] = '\0';
	string str(array);
	if (str == "12345678") cout << "ascending";
	else if (str == "87654321") cout << "descending";
	else cout << "mixed";
    
    return 0;
}

for문을 딱 8개만 돌리면서 값을 받기 때문에 배열에 개행문자(\0)가 자동으로 저장이 되지 않는다. 그래서 숫자를 입력받는 반복문을 다 돌고 array[8] = '\0'; 이란 문장을 적어주었다. 

받은 배열을 String으로 변환하고 "12345678", "87654321"이란 문자열과 비교하여 결과를 출력하였다. 

 


char배열 vs String : 문자열 비교

int main() {
	char array[9];
	for (int i = 0; i < 8; i++) {
		cin >> array[i];
	}
	array[8] = '\0';
	string str(array);
	cout << "str: " << str << endl;
	cout << "array: " << array << endl;
	if (str == "12345678") cout << "str: ascending" << endl;
	else if (str == "87654321") cout << "str: descending" << endl;
	else cout << "str: mixed" << endl;

	if (array == "12345678") cout << "array: ascending" << endl;
	else if (array == "87654321") cout << "array: descending" << endl;
	else cout << "array: mixed" << endl;
	return 0;
}

 

문제를 여러 방식으로 풀어보다가 이상한 점이 있어서 이런식으로 char배열과 string배열을 비교할려고 출력을 해봤다. 

char array를 받고 그대로 배열을 출력한것과 String클래스를 사용해서 변환한 문자열이 출력되는 모양은 같은데 "12345678"과 같냐고 묻는 if문에는 서로 다른 출력이 나왔다. 

 

	if (array == "12345678") cout << "array: ascending" << endl;
	else if (array == "87654321") cout << "array: descending" << endl;

 

원인은, 문자열을 비교할 때 char 배열을 이용한 문자열의 경우 변수는 배열의 시작주소를 가리키므로 == 연산자를 사용하면 동일한 값을 가지고 있더라도 주소가 다르기 때문에 반드시 '다르다'라고 판정하게 된다. 

 

그리고 stirng문자열을 사용할 때 ==연산을 사용하면 연산자 오버로딩이란 개념에 의해 String클래스에 정의되어 있는 operator==연산:(compare함수와  비슷함)을 오버로딩하여 수행한다. 

 

따라서 결과적으로 위와 같은 출력이 나오게 된다. 

 

 

*참고

[C/C++] string 문자열 비교 ==? compare? strcmp? (tistory.com)

 

[C/C++] string 문자열 비교 ==? compare? strcmp?

문자열 비교값을 비교할 때 보통 == 연산자를 이용하여 동일 여부를 알아낸다하지만 문자열의 경우 == 연산자를 사용하면 원치 않은 결과를 가져올 수도 있다이는 값은 같을지라도 값이 저장된

choryeonworkshop.tistory.com

 


\0(null) 문자의 역할

char형 배열 즉, 문자열에서 널문자의 역할은 주로 문자열의 끝을 나타내는 것입니다.
문장마다 길이가 다르듯이 문자열을 표현할 때는 메모리 할당량도 일정하지 않고,
메모리에 저장될 때 해당 문자열의 끝이 어디인지 모르기 때문에 널문자가 필요한 것입니다.

#include <iostream>
//#include <cstring>
using namespace std;

int main() {
	char array[9];
	for (int i = 0; i < 8; i++) {
		cin >> array[i];
	}
	array[8] = '\0';
	string str1(array);
	cout << "str1: " << str1 << endl;
	if (str1 == "12345678") cout << "str1: ascending" << endl;
	else if (str1 == "87654321") cout << "str1: descending" << endl;
	else cout << "str1: mixed" << endl;

	array[8] = '0';
	string str2(array);
	cout << "str2: " << str2 << endl;
	if (str2 == "12345678") cout << "str2: ascending" << endl;
	else if (str2 == "87654321") cout << "str2: descending" << endl;
	else cout << "str2: mixed" << endl;


	return 0;
}

 

나의 얄팍한 생각으로 \0은 출력할때만 끝을 알려주는 문자이고, char배열을 array[9]라고 선언했으니 파일이 실행되면서 문자열을 사용하면  딱 그 부분만큼만 접근한다고 생각하고 있었다. 

하지만 위에 인용 그대로 문자열의 끝이라고 명시해 주는 문자이기 때문에 널 값을 붙여주지 않으면 일정하지 않은 메모리 할당량 뒤에 있는 쓰레기 값까지 읽어들이게 되서 문제를 일으킨다. 

 

 

*참고

(C/C++) 배열 핵심 요약 - 선언, 초기.. : 네이버블로그 (naver.com)

 

(C/C++) 배열 핵심 요약 - 선언, 초기화, 길이, 쓰레기값 골라내기

배열은 일련의 데이터를 모아 놓은 집합체로 다수의 데이터를 저장하고 처리하는 경우에  유용하게 사...

blog.naver.com

 

 

지적할점이나 질문이 있다면 댓글로 알려주세요