본문 바로가기

C++/FOCU_C++

C++ chpt4.

문자열 string

본 내용에 앞서 지난 chpt2 에서 다룬 getline 에 대해 잠깐 살펴보고자 한다.

char line[256];
cin.getline(line, 256);

 

위 코드에서는 현재 두 가지 문제점을 가지고 있다

  • 아무것도 읽지 못했을 때의 동작
  • 문장 길이가 256 을 넘겼을 때의 동작(주어진 버퍼의 크기보다 문장길이가 클 때)

 

또한 코드 표준 시각에서 바라봤을 때도 그리 좋은 코드는 아니다

 

현재 위 코드에선 '256' 이라는 어떠한 기준 값을 직접적으로 숫자로 작성한 것을 '매직넘버'라고 부른다

 

매직넘버의 단점

  • 256 이 왜 256 으로 설정했는지는 기존 지식을 인지한 사람만 이해할 수 있음
  • 같은 숫자가 여러 곳에 있을 때 수정이 어렵고 실수하기 쉬움
  • 256 이란 숫자가 다른 의미로도 사용했을 경우 헷갈릴 수 있음
  • 정책 변경 시(PC 의 최대값이 바뀐다거나) 모든 코드에서 직접 하나하나 수정해야 됨

그래서 아래와 같은 방식을 추구함

#define LINE_LENGTH 256;
char line[LINE_LENGTH];
getline(line, LINE_LENGTH);

 

 

다시 본론으로 돌아와서 getline 의 단점을 보완하고자  C++ 에서는 std::string 클래스를 지원하고 있다.

#include <string>
std::string firstName;
std::cin >> firstName;

 

std::string 클래스를 이용한 문자열은 길이가 증가할 수 있다.

 

아래의 여러 예시들을 통해 C 와 비교하면서 알아보자

 

 대입(assignment) 과 덧붙이기(appeding)

// C
char firstName[20] = "POPE";
char fullName[20];

// 대입 - 안전하지 않음
strcpy(fullName, firstName);
// 덧붙이기 - 안전하지 않음
strcat(fullName, " KIM");

-----------------------------------------------------------

// C++
string firstName = "POPE";
string fullName = "John Doe";

// 대입
fullName = firstName;
// 덧붙이기
fullName += " KIM";

 

 

문자열 합치기(concatenation)

// C

char fistaName[20] = "POPE";
char lastName[20] = "KIM";
char fullName[40];

snprintf(fullname, 40, %s %s, firstName, lastName);

---------------------------------------------------------------------------------

// C++

string firstName = "POPE";
string lastName = "KIM";
string fullName;

fullName = firstname + " " + lastName;

 

 

비교(relational)연산자

// C

if (strcmp(firstName1, firstName2) == 0)
{
}

if (strcmp(firstName1, firstName2) > 0)
{
}

-------------------------------------------------------------------

// C++

if (firstName1 == firstName2)
{
}

if (firstName1 > firstName2)
{
}

 

 

size(), length(), c_str()

 

size(), length()

문자열 길이를 반환

cout << firstName.size() << endl;
cout << firstname.length() << endl;

 

c_str()

const char* 반환

해당 string 이 가지고 있는 문자 배열의 시작 주소를 가라키는 포인터를 반환

C++ 은 C 와 같이 동작할 수 있게 구조되었으며 C 는 string 클래스가 배열로된 string 을 사용하기 때문에 그에 맞춰 동작될 수 있도록 만들어진 기능

또한 운영체제 함수 호출시에도 대부분 C 기반이라 char * 를 요구하기 때문이기도 하다

string line;
cin >> line;
cost char* cLine = line.c_str();

 

 

string 내부 문자 바꾸기

 

C 와 같은 방식

string firstName = "POKE";
char letter = firstName[1];
// 문자 변환
firstName[2] = 'P';

-----------------------------------------

[2] <- 이 부분은 함수로써 반환값을 통해 해당 문자를 접근하며, 참조를 통해 반환한다.

std::string 내부 구현 (간소화)
char& operator[](std::size_t pos);        // 비-const 버전
const char& operator[](std::size_t pos) const;  // const 버전

비 const 객체에서 []를 호출하면 참조(char&) 를 반환
const 객체에서 호출하면 읽기 전용 참조(const char&) 반환

 

at() 방식

char letter = firstname.at(1);
firstname.at(2) = 'P';

 

 

문장 한 줄 읽기

string mailHeader;
getline(cin, mailHeader); // '\n' 만날 때까지 cin 에서 문자들을 꺼내서 mailHeader 에 저장

getline(cin, mailHeader, '@'); // '@' 문자 만날 때까지 cin 에서 문자들을 꺼내서 mailHeader 에 저장

 

구분자(기본: '\n') 를 만나거나 EOF 를 만나면 종료한다.


sstream

 

자주 사용되지는 않지만 일다 조금만 살펴보자

 

std::istringstream

  • cin 과 비슷, 키보드 대신 string 으로부터 읽어옴
  • sscanf() 와 비슷

std::ostringstream

  • cout 과 비슷, 콘솔 대신 string 에 출력
  • sprintf() 와 비슷

참고 : cout, cin 도 스트림


C++ 에서 C 헤더 사용 방법

 

C C++
<string.h> <cstring>
<stdio.h> <cstdio>
<ctype.h> <cctype>

 

기존 C 에서 '.h' 를 빼고, C 함수임을 알리기 위해 해당 해더 앞에 'c' 를 추가

 


string 활용 예문

 

문자열 뒤집어 덧붙이기

#include <iostream>
#inlcude <string>
#inlcude "MirrorString.h"

using namespace std;

namespace samples
{
    void MirrorStringExample()
    {
        string line = "hello world!";

        cout << "string to mirro: " << line << endl;

        for (int i = (int)line.size() - 1;. i >= 0; --i)
        {
            line += line[i];
        }
        cout << "Mirrored String" << line << endl;
    }
}

int main()
{
    samples::MirrorStringExample();
    return 0;
}

 

'C++ > FOCU_C++' 카테고리의 다른 글

C++ chpt6.  (1) 2025.05.16
C++ chpt5.  (0) 2025.05.04
C++ chtp3.  (0) 2025.05.03
C++ chpt2.  (0) 2025.04.29
C++ chpt1.  (0) 2025.04.28