C++ - 문자열

이강민·2023년 8월 23일

C++

목록 보기
13/22
post-thumbnail

문자열

문자열 정의 후 항상 문자의 끝은 null문자가 할당되어 문자의 끝을 알려준다.

  • 1byte의 문자열

    char szchar[10] = "abcdef";
    각각의 배열 공간에 1byte씩 할당되어 있다.
  • 2byte의 문자열
    wchar_t wc = L'a';
    wchar_t szWchar[10] = L"abcdef";
    • 2byte의 문자열은 문자 1개당 2byte씩 할당된다.

같은 2byte 타입이라도 문자열 형태의 초기식은 wchar와 char타입만 허용한다.
포인터와 배열과 같이 const를 적용할 수 있다.

// 문자열에 할당된 주소를 직접적으로 가져옴
const wchar_t* pchar = L"abcdef";
// 그러나 프로그램 코드영역의 코드를 수정하는 것은 불가하기에 const로 받으며
// 아래와 같이 실행되지 않는다.
//pcahr[2] = 'z'; // *(pchar +1) = 'z';

멀티바이트

멀티바이트의 문제점 ): 표준으로 사용하지 않아 인코딩의 문제가 있을 수 있다. 따라서 한글을 사용하려면 와이드바이트시스템, wchar_t를 사용하는 것이 유리하다.
한글은 2byte의 공간을 사용하니 처음부터 2byte의 타입인 wchar_t를 사용하자는 것이다.

wchar.h 라이브러리

wcslen

  • 문자열의 갯수를 알려주는 함수
  • wcslen, wchar_t타입의 주소를 매개변수로 받아서 문자열의 갯수를 return함.
  • const wchar_t* _String을 매개변수로 받는 것을 보아서 문자열의 명을 그대로 넘긴다는 것이며 배열의 원본을 바꾸지 않다는 것을 알려주기 위해 const로 받는다.
wchar_t szName[10] = L"Rabmond";
int iLen = wcslen(szName);
printf("%d\n", iLen);

wcslen 라이브러리 직접 구현해보기

unsigned int GetLength(const wchar_t* _pStr) {
	_pStr[0];
	int i = 0;
	//while (true) {
	//	// 다음 문자열을 확인함. 2바이트 만큼 검사해나아감
	//	// 아래의 코드와 같음
	//	//wchar_t c = _pStr[i];
	//	wchar_t c = *(_pStr + i);
	//	// '\0' 또는 0 일 경우 break로 반복문 탈출
	//	if (c == 0) {
	//		break;
	//	}
	//	// 검사 후 i 증가
	//	++i;
	//}
	// while문에 조건식으로 표현가능
	//비교 조건은 상수를 좌변에 두는 것이 실수를 줄인다.
	while ('\0' != _pStr[i]) {
		++i;
	}
	return i;
}

사용자 정의함수를 통해 길이를 구해볼 수 있다.

wcscat_s

  • 문자열 이어붙이기
    wchar_t szTestW[10] = L"abc한글";
    // 원본문자열, 문자열의 길이, 붙이고자 하는 문자
    wcscat_s(szTestW, 10, L"df");

라이브러리 직접만들어보기

원본의 데이터를 수정할 수 있도록 매개변수로 받고 문자열 초과여부 검사한뒤
원본 문자열의 끝인덱스에서부터 추가 문자열을 붙인다.

void StrCat(wchar_t* _pDest, unsigned int _iBufferSize, const wchar_t* _pSrc) {
	// 사용자 정의함수의 문자열 길이 함수를 가져왔다.
	int iDestLen = GetLength(_pDest);
	int iSrcLen = GetLength(_pSrc);
	//문자열 초과 여부 검사
	if (_iBufferSize < (iDestLen + iSrcLen + 1)) {
		assert(nullptr);
	};
	//문자열 합치기
	//1. 원본 문자열의 \0 부분을 찾음
	// Dest 문자열의 끝 인덱스 
	// iDestLen;
	//2. 반복적으로 src 문자열을 Dest 끝 위치에 복사하기
	// src 문자의 \0 문자를 넣기 위해 +1함.
	for (int i = 0; i < iSrcLen+1; ++i)
	{
		_pDest[iDestLen + i] = _pSrc[i];
	}

wcscmp

  • 문자열 일치 여부 확인
  • 같으면 0, 왼쪽 문자열이 높으면 1, 우측 문자열이 높으면 -1
	int iRet = wcscmp(L"cccc",L"cccc");

라이브러리 직접 만들어보기


int GetCmp(const wchar_t* _pSrc, const wchar_t* _pDest) {
	//문자열비교
	// _pSrc , _pDest  동시에 비교한다. 
	// 첫자리부터 순서대로 비교하며 같으면 다음 자리 _pSrc가 하나라고 크면 1,
	// _pSrc가 하나라도 작으면 -1를 return한다.
	// 만약 모든 자리수가 같으면 0을 return한다. 
	//비교는 '\0'까지 비교한다. 
	int iSrcLen = GetLength(_pSrc);
	int iDestLen = GetLength(_pDest);
	int i = 0;
	int result = 0;
	while (true) {
		if (iSrcLen < (i + 1) && iDestLen < (i + 1)) {
			break;
		}
		if (_pSrc[i] > _pDest[i] || (_pDest[i] == '\0' && _pSrc[i]!= '\0')) {
			result = 1;
			break;
		}
		if (_pSrc[i] < _pDest[i] || (_pSrc[i] == '\0' && _pDest[i] != '\0')) {
			result = -1;
			break;
		}
		if ((iSrcLen == iDestLen) && _pSrc[i] == _pDest[i]) {
			result = 0;
		}

		++i;
		
	}
	return result;
}

추가 풀이

int StrCmp(const wchar_t* _left, const wchar_t* _right) {
	int leftLen = GetLength(_left);
	int rightLen = GetLength(_right);

	int iReturn = 0;
	int iLoop = leftLen;
	if (leftLen < rightLen) {
		iLoop = leftLen;
		iReturn = 1;
	}
	else if (leftLen > rightLen) {
		iLoop = rightLen;
		iReturn = -1;
	}

	for (int i = 0; i < iLoop; ++i) {
		if (_left[i] < _right[i]) {
			return -1;
		}
		else {
			return 1;
		}
	}
	return iReturn;
}
profile
AllTimeDevelop

0개의 댓글