Programming Language/C++

Ch06. 복합데이터 - 03. 문자열

hustle_D 2025. 4. 1. 23:15
반응형

 

1. 문자열

우리가 기존에 사용했었던

std::cout << "String" << std::endl;

이런 문자열들은 사실 

char str[] = "String";
std::cout << str << std::endl;

이와 같이 문자로 구성된 배열의 일종이다.

 

이건 실제로

char str[] =  {'S', 't', 'r', 'i', 'n', 'g', '\0'}

과 같이 str에 들어가 있게 된다.

그래서 출력을 해보면

이렇게 출력되는 것을 알 수 있다.

마지막에 빈것은 널문자라고 해서 문자열의 종료 지점을 알려주는 문자로 확인하기 위해서 타입을 int로 바꿔보면

이렇게 널문자가 나온다는 것을 알 수 있다.

 

이 널문자는 문자열을 출력할때 이 문자열이 어디까지 존재하는지를 인식시켜주기 위함이다.

그래서 만약에 널문자의 위치에 다른 문자를 끼워 넣은 다음에 

str을 출력해보면

이런식으로 그 이후의 이상한 문자를 출력하는 것을 볼 수 있다.

이건 널문자를 찾지 못해 다음 널문자가 존재하는 부분까지 출력했기 때문이다.

 

다시 정상적으로 하기 위해서는 마지막 위치에 

이렇게 널문자(\0)을 넣어주면 

정상적으로 출력된다.

 

크기를 지정한 문자열의 초기화

크기를 지정한 문자열에 크기보다 작은 값을 삽입하면 초과되는 범위는 모두 널문자로 초기화된다.

그렇기에 이 상태에서 그냥 str을 출력하면 

문자열을 삽입한 위치까지만 출력하게 된다.

 

문자열의 비교

이렇게 같은 정보가 들어 있는 문자열을 비교할때 

이렇게 비교하면 비교가 가능할까?

이것도 결국 주소값을 반환하기 때문에 값으로 비교하는 기능을 하지는 못한다.

 

이럴 경우에 문자열을 서로 비교하기 위한 함수인 strcmp라는 함수를 사용하면 된다.

더보기

strcmp

strcmp는 C 스타일 문자열(char 배열)을 비교하는 함수로, 두 문자열이 같은지, 어떤 쪽이 더 큰지를 비교하여 정수 결과를 반환한다.

 

함수 원형

int strcmp(const char* str1, const char* str2);

함수의 원형은 위와 같이 생겼고 문자열 두개를 넣음으로써 0이 나오면 문자열이 서로 같음을 나타내고, 0보다 작은 값이 나올 경우 str1이 str2보다 작음을 나타내고(사전 순으로 앞인 값), 0보다 큰 경우엔 str1이 str2보다 큼을 나타낸다(사전순으로 뒤인 값)

 

문자열의 복사

문자열의 복사 또한 그냥 

이렇게 넣어주는 방식은 불가능하다.

 

그럼 strcpy를 사용하면 가능할까 ?

더보기

strcpy

strcpy는 C 스타일 문자열을 복사하는 함수로, 소스 문자열(src)의 내용을 목적지(dest)에 그대로 복사해준다.

 

함수 원형

char* strcpy(char* dest, const char* src);

- dest: 문자열을 복사할 대상 (목적지)

- src: 복사할 원본 문자열

- 반환값: dest (복사된 문자열의 시작 주소)

문제가 없어 보이는데 실행해보면

에러가 발생한다

이는 아래와 같이 

보안 이슈로 인해서 발생하는 에러로

이렇게 배열의 범위를 넘어서는 배열을 집어 넣으려고 하면

이렇게 넘어서는 범위까지 침범했다고 알린다.

실행시켜보면 

이렇게 에러가 발생한다.

이 경우엔 scanf를 사용했을때와 같이 

이걸 최상단에 넣어주면

정상적으로 실행된다.

 

물론 크기가 넘어서는 경우는 이렇게 해도 에러가 발생한다.

이렇게 다른 메모리 공간을 침범할 수 있는 행위는 해서는 안된다.

그렇기에 이걸 Visual Studio에서는 권하지 않는 것이다.

 

문자열의 연결

문자열을 연결해 붙이는 방법은 strcat이라는 함수를 사용하면된다.

더보기

strcat

strcat은 C 스타일 문자열에서 두 문자열을 이어붙이는 함수(문자열 연결)로 dest 문자열의 끝에 src 문자열을 붙여준다.

끝에 붙이는 문자열도 널 문자(\0)를 포함해서 처리된다.

함수원형

char* strcat(char* dest, const char* src);

- dest: 붙일 대상 문자열 (기존 문자열)

- src: 뒤에 붙일 문자열

이 경우에도 붙여지는 문자열에는 충분한 크기를 가지고 있어야만 한다.

이렇게 크기가 작은 경우에는 크기를 넘어섰다고 알리면서 실행하더라도 에러를 발생시킨다.

 

문자를 숫자로 숫자를 문자로

 

이렇게 숫자를 문자열로 넣은 경우에 

이렇게 atoi(ASCII to Interger)함수를 사용해서 

정수로 만들수도 있고 

이렇게 atof(ASCII to float)를 통해서 

실수로도 만들어 줄 수 도 있다.

 

숫자를 문자로 만드는 경우는 

이렇게 sprintf 함수를 사용해서 num에 있는 숫자를 str에 넣어줄 수 도 있다.

더보기

sprintf

sprintf는 printf처럼 서식 문자열(format string)을 사용하지만, 출력을 문자열로 저장하는 함수로 콘솔에 출력결과를 출력하는게 아니라 문자열 버퍼에 저장한다.

함수원형

int sprintf(char* buffer, const char* format, ...);

- buffer: 포맷된 결과를 저장할 문자 배열 (C 문자열)

- format: printf와 같은 포맷 문자열 (%d, %s 등)

-  ...: 가변 인자 (출력할 값들)

 

이 경우엔 format을 변경해주기만 하면 

다양한 타입을 넣어주는 것도 가능하고

 

다양한 값을 받아 

문자열에 저장하는 것도 

가능하다.

 

 

입력할때 주의할 점

입력을 받아서 사용할때 주의할점은 문자배열의 크기를 상정해야 한다는 점

 

그리고 입력시 동일하게 문제가 됐던 공백 문자로 인해 다음 입력이 불가능 해지는 점에 대해서 유의 해야한다.

그래서 문자열을 입력 받을 때는 그냥 저렇게 cin으로 받는게 아니라 cin의 getline이라는 함수를 사용해서 

이렇게 입력을 받아주면 

이렇게 원하는 대로 입력을 받을 수 있다.

더보기

std::cin.getline()

std::cin >> 변수는 공백(스페이스, 탭, 엔터)을 기준으로 단어 단위 입력을 받으나 std::getline()은 한 줄 전체를 통째로 입력받는 함수이다.

 

함수원형

std::cin.getline(char* str, std::streamsize count);

- str: 입력받을 C 스타일 문자열을 저장할 배열 주소

- count: 입력받을 최대 길이+1 (널 문자 포함)

   ㄴ count - 1개의 실제 문자를 읽고 마지막에 널 문자 "\0"을 자동으로 붙여준다

 

반응형