검수요청.png검수요청.png

"문자열"의 두 판 사이의 차이

위키원
이동: 둘러보기, 검색
(새 문서: '''문자열'''(String)이란 기호의 순차 수열을 말한다. == 참고 자료 == == 같이 보기 == * Java 문자열 * C 문자열)
 
 
(사용자 3명의 중간 판 20개는 보이지 않습니다)
1번째 줄: 1번째 줄:
'''문자열'''(String)이란 기호의 순차 수열을 말한다.
+
'''문자열'''(string)이란 [[데이터]]로 다루는 일련의 문자를 의미한다. 문자열은 기호의 순차 수열을 포함하기 때문에 숫자를 포함하는 것이어도 계산하는 숫자로서가 아닌 코드의 일부로 쓰인다면 문자열이라고 할 수 있다.
  
== 참고 자료 ==
+
==개요==
 +
일반적으로 문자열은 말 그대로 문자 등을 1차원적으로 나열한 것을 의미한다. 이때 문자의 의미는 말 그대로 문자(character)일 수도 있으나 하나의 계속되는 비트(bit), 레코드(record) 등을 나타낸다. 이들을 각각 문자열(character string), 비트 스트링(bit string), 레코드 스트링(record string)이라고 한다. 문자열에는 하나의 자료를 구성하기 위하여 일련의 문자 집합으로 구성된 정보가 담기게 된다. [[프로그래밍]]에서 문자열은 일반적으로 취급하는 데이터형의 하나로 인식된다. 사용하는 컴퓨터 시스템으로 인식할 수 있으며, 비트 배치를 갖는 문자로 이루어지는 집합에서 취한 0개 이상의 문자로 배열이 이루어진다. 이때 요소는 문자 [[인코딩]]과 관련된 문자를 대표하는 일련의 자료값을 저장하고 있는 자료형으로 이해할 수 있다. 여기서 문자 인코딩의 경우 더 일반적인 배열 자료형과 차이가 있다. 이러한 환경에서 이진 문자열(binary string)과 바이트 문자열(byte string)이라는 용어는 저장된 자료가 반드시 텍스트를 표시하지 않아도 되는 문자열을 표시하는 데 사용된다. 문자열 자료형으로 선언된 변수의 경우, 미리 정의된 어느 정도의 기호를 소유할 수 있는 메모리에 기억 자료를 할당하는 것이 보통이다. 문자열이 소스 코드에 보이면 그 문자열을 스트링 리터럴(string literal)이라고 일컫는다.
 +
 
 +
==특징==
 +
char형 [[변수]]로 문자열을 저장하기에는 당연히 무리가 따른다. char형 변수는 문자 1개만을 저장하기 위한 변수이기 때문이다. 문자열을 저장하기 위해서는 char형 배열이 필요하다. 예를 들어 5글자의 문자를 저장하고자 한다면 크기가 5인 char형 배열을 생성하여 저장하면 된다. 1바이트(byte) 당 한글자가 저장이 되며 배열의 크기는 지정이 가능하다. 문자열은 이처럼 char형 배열로 저장이 가능하다.<ref name="자료1"> SLL, 〈[https://m.blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220488567828&proxyReferer=https%3A%2F%2Fwww.google.com%2F C언어 문자열(string) 기본개념]〉, 《네이버블로그》, 2015-09-22</ref>
 +
 
 +
===문자상수/문자열상수===
 +
문자상수는 'A'와 같이 작은따옴표(' ')로 표현한다. 상수라고 해서 숫자만 있는 것이 아님을 유의해야 한다. 문자 상수란 문자의 값이며 변하지 않는 수이다. 예를 들어서 'A'라고 하면 이 A는 문자값이다. 하지만 char A; 라고 하면 이 A는 문자값이 아니라 문자를 저장하기 위한 변수다. A라고 하는 이름은 변하지 않지만 그 안에 들어가는 문자상수(값)은 언제든 변할수 있기 때문이다.
 +
유사하게 문자열상수란 문자열값을 의미하며, 큰따옴표(" ")로 표현한다.  "Hello", "Be Happy~" 와 같은 것들이 문자열상수이다.<ref name="자료1"> SLL, 〈[https://m.blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220488567828&proxyReferer=https%3A%2F%2Fwww.google.com%2F C언어 문자열(string) 기본개념]〉, 《네이버블로그》, 2015-09-22</ref> [[C 언어]]에서는 큰따옴표를 사용해 표현되는 문자열을 문자열 상수(string constant)라고 한다. 상수라고 표현하는 이유는 해당 문자열이 이름을 가지고 있지 않으며, 문자열의 내용 또한 변경할 수 없기 때문이다. C언어에서 문자열은 [[메모리]]에 저장된 일련의 연속된 문자들의 집합을 의미한다. 따라서 문자형 [[배열]]을 선언하면 이 배열이 곧 문자열 [[변수]]가 된다.<ref name="자료2">〈[http://tcpschool.com/c/c_string_string 문자열]〉, 《TCP School》</ref>
 +
문자열에 대한 예를들면 'A'는 문자이지만, 'ABCD'는 문자열이다. 즉 문자가 여러개 모인것을 지칭한다. 문자는 char형 변수에 저장이 된다. 간단한 코드로 보면,
 +
 
 +
char a = 'A';
 +
char b = 'D';
 +
 
 +
와 같이 저장하면 된다. char형은 1바이트로 할당되며 문자는 1바이트로 저장이 가능하다는 말이다.
 +
 
 +
===문자열의 초기화===
 +
문자열을 초기화하기 위한 방법은 세 가지로 나뉜다.
 +
char str[6]= { 'H', 'e', 'l', 'l', 'o'. '\0'};
 +
 +
char str[6]= "Hello";
 +
 +
char str[]= "Hello";
 +
A는 크기가 6인 문자배열을 선언하고 각 자리에 들어갈 문자를 순서대로 지정해주는 것이다. B는 크기가 6인 문자배열을 선언함과 동시에 문자열을 대입하는 방법이다. 큰따옴표로 표현해주면 되겠다. 주의할점은 크기가 6이므로 이 크기를 벗어나는 문자열상수는 초기화할 수 없다. C는 문자열상수로 초기화하지만 배열의 크기를 지정하지 않는다. 이런 경우 문자열상수의 크기에 따라 자동으로 str배열의 크기를 지정해주게 된다. C가 문제도 없고 가장 편해보이지만, 문자열이 긴 경우에 개발자가 그 크기를 직접 계산해서 알고 있어야 한다는 불편함이 따른다. 직관적으로 크기도 알고 문자열도 알수 있는 B가 가장 무난하다고 생각할 수 있겠다.<ref name="자료1"> SLL, 〈[https://m.blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220488567828&proxyReferer=https%3A%2F%2Fwww.google.com%2F C언어 문자열(string) 기본개념]〉, 《네이버블로그》, 2015-09-22</ref>
 +
 
 +
===문자열의 출력===
 +
저장한 문자열을 출력에 대해 printf 함수만을 예로 들어 설명하면, printf 함수를 사용할 때 출력되는 형태를 지정하기 위해서 형식지정 문자 또는 서식문자 라고 불리는 %로 시작하는것을 붙인다. 예를 들어 %d는 십진수정수 형태로 출력하라는 %x는 16진수, %lf는 double형타입, %o, %u 등등 여러 가지가 지정되어 있다. 문자는 %c로 출력하고, 문자열은 %s로 출력하면 된다.<ref name="자료1"> SLL, 〈[https://m.blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220488567828&proxyReferer=https%3A%2F%2Fwww.google.com%2F C언어 문자열(string) 기본개념]〉, 《네이버블로그》, 2015-09-22</ref>
 +
 
 +
char c ='A';
 +
 +
char str[10]= "ILoveYou";
 +
 
 +
이제 출력하려면,
 +
 
 +
printf("%c", c);
 +
 +
printf("%s", str);
 +
 
 +
%s로 지정을 하면되는데, 이에 대응되는 변수부분이 str 즉 배열의 이름이 된다. 그런데 str은 배열의 이름이고, 배열의 이름은 바로 이 배열 전체를 대표하는 이름이자 첫번째 주소값을 가지고 있는 포인터의 성질을 갖는다. printf도 함수이니 str은 함수의 매개변수가 된다. printf 함수가 문자열을 출력할 때 이 문자열이 저장되어 있는 가장 첫 번째 주소값을 주면 출력해준다는 사실을 알 수 있다. 즉 %s를 이용해 문자열을 출력할때 이에 대응되는 우측부분에 들어가는 데이터의 타입은 바로 char* 이다.<ref name="자료1"> SLL, 〈[https://m.blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220488567828&proxyReferer=https%3A%2F%2Fwww.google.com%2F C언어 문자열(string) 기본개념]〉, 《네이버블로그》, 2015-09-22</ref>
 +
 
 +
===NULL 문자('\0')===
 +
[[널]](NULL)이라는 문자는 상징적으로 사용되며 사실상 그 값은 0이다. 문자는 역슬래쉬0 = \0으로 표현한다. 문자열은 항상 마지막 공간에 널 문자 1개를 포함하고 있다. 만약 'ILoveYou'를 저장하고 싶다면 실제 문자는 8개지만 마지막에 널문자가 추가되어 있어야만 한다. 초기화 방법에서 A는 각 메모리공간 하나하나를 지정하고 있기때문에 반드시 마지막에 널문자를 넣어주어야 한다. B와 C같은 경우는 문자열 상수로 초기화되므로 자동으로 들어가게 된다. 즉, 보이지 않지만 분명 1바이트를 차지하고 있는 널문자가 존재하고 있는 것이다. 따라서 char형 배열에 문자를 저장하고 싶다면 반드시 문자의 갯수 + 1에 해당하는 크기를 할당해 놓아야 제대로 된 저장이 가능하다.<ref name="자료1"> SLL, 〈[https://m.blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220488567828&proxyReferer=https%3A%2F%2Fwww.google.com%2F C언어 문자열(string) 기본개념]〉, 《네이버블로그》, 2015-09-22</ref> 문자형 배열로 선언된 문자열 변수는 문자열의 끝을 프로그램에 따로 알려주어야 한다. 그래야만 프로그램이 실제 문자열에 속한 값과 그 외의 쓰레깃값을 구분할 수 있기 때문이다. 따라서 C 언어에서는 문자열에 속한 데이터가 끝나면, 문자열의 끝을 의미하는 문자를 하나 더 삽입해 준다. 이 문자를 널 문자라고 하며, '\0'으로 표시하고 아스키코드값은 0이다.<ref name="자료2">〈[http://tcpschool.com/c/c_string_string 문자열]〉, 《TCP School》</ref>
 +
 
 +
===문자열 이스케이프 시퀀스===
 +
:{| border="1" cellpadding="5" cellspace="0"
 +
|-
 +
| width="16%" | 이스케이프 시퀀스
 +
| align="center" | 문자 이름 || 유니코드 인코딩
 +
|-
 +
|\' || 작은따옴표 || 0x0027
 +
|-
 +
|\" || 큰따옴표 || 0x0022
 +
|-
 +
|\\ || 백슬래시 || 0x005C
 +
|-
 +
|\0 || Null || 0x0000
 +
|-
 +
|\a || 경고 || 0x0007
 +
|-
 +
|\b || 백스페이스 ||0x0008
 +
|-
 +
|\f || 폼 피드 ||0x000C
 +
|-
 +
|\n || 줄 바꿈 ||0x000A
 +
|-
 +
|\r || 캐리지 리턴 ||0x000D
 +
|-
 +
|\t || 가로 탭 ||0x0009
 +
|-
 +
|\v || 세로 탭 ||0x000B
 +
|-
 +
|\u || 유니코드 이스케이프 시퀀스(UTF-16) || \uHHHH (범위: 0000-FFFF; 예제: \u00E7 “ç” =)
 +
|-
 +
|\U || 유니코드 이스케이프 시퀀스(UTF-32) || \U00HHHHHH (범위: 000000-10FFFF; 예: \U0001F47D = “👽”)
 +
|-
 +
|\x || 길이가 변하는 경우를 제외하고 “\u”와<br>유사한 유니코드 이스케이프 시퀀스한다. || \xH[H][H][H] (범위: 0-FFFF; 예: \x00E7 나 \x0E7 또는 \xE7 "ç" =)
 +
|+ 이스케이프 시퀸스<ref name="자료4">〈[https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/strings/ 문자열(C# 프로그래밍 가이드)]〉, 《Microsoft》, 2019-06-27</ref>
 +
|}
 +
 
 +
===형식 문자열===
 +
형식 문자열은 콘텐츠가 [[런타임]]에 동적으로 결정되는 문자열이다. 형식 문자열은 문자열 내의 중괄호 안에 ‘보간된 식’이나 자리 표시자를 포함하여 만들어진다. 중괄호({...}) 안의 모든 내용은 런타임에 하나의 값으로 확인되고 형식화된 문자열로 출력된다. 형식 문자열을 만드는 두 가지 방법은 문자열 보간 및 복합 형식 지정이다.<ref name="자료4">〈[https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/strings/ 문자열(C# 프로그래밍 가이드)]〉, 《Microsoft》, 2019-06-27</ref>
 +
 
 +
===문자열 보간===
 +
C# 6.0 이상에서 사용 가능한 ‘보간된 문자열’은 $ 특수 문자로 식별되고 중괄호 안에 보간된 식을 포함한다. 코드의 가독성과 유지 관리를 개선하려면 문자열 보간을 사용한다. 문자열 보간은 String.Format 매소드와 동일한 결과를 제공하지만 더 편리하고 인라인 명확성이 향상된다.<ref name="자료4">〈[https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/strings/ 문자열(C# 프로그래밍 가이드)]〉, 《Microsoft》, 2019-06-27</ref>
 +
 
 +
===복합 형식 지정===
 +
String.Format은 중괄호 안에 자리 표시자를 활용하여 형식 문자열을 만든다. 이 예제는 위에서 사용한 문자열 보간 방법과 유사한 출력을 생성한다.
 +
 
 +
===부분 문자열===
 +
부분 문자열은 문자열에 포함된 임의의 문자 시퀀스다. 원래 문자열 일부에서 새 문자열을 만들려면 서브스트링(Substring) 매소드를 사용해야 한다. 인덱스오브(IndexOf) 매소드를 사용하면 부분 문자열 항목을 하나 이상 검색할 수 있다. 지정된 부분 문자열의 모든 항목을 새 문자열로 바꾸려면 리플레이스(Replace) 매소드를 사용한다. 서브스트링 매소드와 마찬가지로, 리플레이스는 실제로 새 문자열을 반환하며, 원래 문자열은 수정되지 않는다.<ref name="자료4">〈[https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/strings/ 문자열(C# 프로그래밍 가이드)]〉, 《Microsoft》, 2019-06-27</ref>
 +
 
 +
===개별 문자 액세스===
 +
문자열에서 개별 문자를 수정해야 하는 기능이 스트링(String) 매소드에서 제공되지 않는 경우에는 스트링빌더(StringBuilder) 개체를 사용하여 개별 문자를 "현재 위치"에서 수정한 후 새 문자열을 만들어 스트링빌더 매소드로 결과를 저장할 수 있다.<ref name="자료4">〈[https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/strings/ 문자열(C# 프로그래밍 가이드)]〉, 《Microsoft》, 2019-06-27</ref>
 +
 
 +
==자바 문자열==
 +
[[자바]](Java) 문자열은 객체이고 문자열 리터를은 큰 따옴표로 묶어 표시한다. 문자열 리터럴도 객체이므로 바로 매소드를 호출할 수 있다.<ref name="자료3"> OffByOne, 〈[https://offbyone.tistory.com/401 자바 문법 - 문자열(String 객체) 다루기]〉, 《티스토리》, 2019-08-11</ref>
 +
 
 +
===문자열 연결===
 +
자바 문자열을 연결하는데는 + 연산자를 사용한다.
 +
 
 +
String h = "Hello ";
 +
String j = "Java!";
 +
 +
String text = h + j;
 +
 +
System.out.println(text);
 +
 
 +
결과)
 +
Hello Java!
 +
 
 +
자바에서 문자열에 연산을 사용하는데 있어서 주의해야 할 점이 있는데, 자바 문자열은 불변(immutable)이라는 점이다. 문자열에 연산을 가하면 현재 문자열을 변경되지 않고 변경된 새 문자열이 만들어져서 반환된다.<ref name="자료3"> OffByOne, 〈[https://offbyone.tistory.com/401 자바 문법 - 문자열(String 객체) 다루기]〉, 《티스토리》, 2019-08-11</ref>
 +
 
 +
String h = "Hello Java!";
 +
String t = h.substring(0, 5);
 +
 +
System.out.println(h);
 +
System.out.println(t);
 +
 
 +
결과)
 +
Hello Java!
 +
Hello
 +
 
 +
많은 문자열을 연결할 경우에는 성능문제로 인해 + 연산자 보다는 스트링빌더(StringBuilder) 객체를 사용한다. 이전에는 스트링빌더 객체를 사용했었는데, JDK 1.5 부터 스트링빌더 객체가 나와서 이것을 사용한다. 스트링버퍼(StringBuffer)와 스트링빌더 객체의 차이점은 스트링버퍼 객체의 매소드는 싱크로나이즈드(synchronized) 되어 있어서 다중 쓰레드에서 안전하고, 스트링빌더는 싱크로나이즈드 되어 있지 않아 다중 쓰레드 환경에서는 사용할 수 없지만 싱글 쓰레드 환경에서 동기화 오버헤드가 없으므로 더 빠르게 동작한다. 그래서 대부분의 경우 스트링빌더를 사용한다.<ref name="자료3"> OffByOne, 〈[https://offbyone.tistory.com/401 자바 문법 - 문자열(String 객체) 다루기]〉, 《티스토리》, 2019-08-11</ref>
 +
 
 +
===문자열 비교===
 +
String 객체를 비교할 때는 equals() 매소드를 사용한다. 기본 타입이 같은지 비교할때 사용되는 == 연산자를 사용하여 객체를 비교하게 되면 객체가 존재하는 메모리상의 주소가 같은지를 비교하게 되어서 잘못된 결과를 보게 될 것이다. 객체인 스트링(String)을 비교할 때는 equals() 매소드를 사용한다.<ref name="자료3"> OffByOne, 〈[https://offbyone.tistory.com/401 자바 문법 - 문자열(String 객체) 다루기]〉, 《티스토리》, 2019-08-11</ref>
 +
 
 +
String h = "Hello ";
 +
String j = "Java!";
 +
 +
if(h.equals(j)) {
 +
 +
    System.out.println("h와 j는 같은 내용을 가지는 문자열 입니다.");
 +
 +
}
 +
 
 +
문자열을 특정 문자열 리터럴과 비교할 경우가 있다. 이 경우 "".equals() 처럼 비교하고자 하는 리터럴의 매소드를 사용하는것이 안전하다. 아래처럼 사용할 경우 h가 null이면 NullPointerException이 발생할 수 있다.
 +
 
 +
if("Hello".equals(h)) {
 +
    ...
 +
}
 +
 
 +
문자열을 사전순으로 정렬했을때의 우선 순위를 비교하려면 compareTo() 매소드를 사용한다.
 +
 
 +
String year = "2018"
 +
int result = "2019".compareTo(year);
 +
 +
if(result > 0) {
 +
    // 현재 년도 보다 큼
 +
} else if(result == 0) {
 +
    // 현재 년도와 같음.
 +
} else if(result < 0) {
 +
    // 현재 년도 보다 작음
 +
}
 +
 
 +
===문자열 매소드===
 +
자주 사용하는 문자열의 매소드들은 아래와 같다.<ref name="자료3"> OffByOne, 〈[https://offbyone.tistory.com/401 자바 문법 - 문자열(String 객체) 다루기]〉, 《티스토리》, 2019-08-11</ref>
 +
* char charAt(int index) : 지정된 인덱스의 한 문자를 반환한다.
 +
* int compareTo(String anotherString) : 두 문자열의 사전적 우선 순위 비교
 +
* int compareToIgnoreCase(String str) : 대소문자를 구분하지 않는 사전적 비교
 +
* boolean contains(CharSequence s) : 문자열을 포함하고 있는지 확인한다.
 +
* boolean endsWith(String suffix) : 문자열의 끝이 인자로 주어진 문자열인지 확인한다.
 +
* boolean equals(Object anObject) : 같은 내용의 문자열인지 비교한다.
 +
* boolean equalsIgnoreCase(String anotherString) : 대소문자를 구분하지 않고 비교한다.
 +
* byte[] getBytes() : 플랫폼 기본 캐릭터셋으로 인코딩된 바이트 배열을 링크한다.
 +
* byte[] getBytes(String charsetName) : 인자로 주어인 캐릭터 셋으로 인코딩된 바이트 배열을 반환한다. 캐릭터셋을 변환하기 위해서 주로 사용됌.
 +
* int indexOf(int ch) : 인자로 주어진 문자가 있는 위치를 반환한다. 없으면 음수를 반환한다.
 +
* boolean isEmpty() : 빈문자열 인지 확인한다.
 +
* int lastIndexOf(int ch) : 인자로 주어진 문자가 마지막으로 나타난 위치를 반환합니다. 없으면 음수를 반환한다.
 +
* int length() : 문자열의 길이를 반환한다.
 +
* boolean matches(String regex) : 인자로 주어진 정규식에 매치되는지 확인한다.
 +
* String replace(char oldChar, char newChar) : 문자열에서 첫번째 인자의 문자를 두번째 인자의 문자로 바꾼다.
 +
* String replace(CharSequence target, CharSequence replacement) : 문자열을 바꾼다.
 +
* String replaceAll(String regex, String replacement) : 정규식을 사용하여 매치되는 문자열을 바꾼다.
 +
* String[] split(String regex) : 정규식에 매치되는 부분을 구분자로 문자열을 분할한다.
 +
* String[] split(String regex, int limit) : 문자열 분할시 두번째 인자로 마지막 빈 요소 처리 및 분할할 갯수를 지정한다.
 +
* boolean startsWith(String prefix) : 인자로 주어진 문자열로 시작하는지 확인한다.
 +
* String substring(int beginIndex) : 문자열에서 인자로 주어인 인덱스 이후의 문자열을 추출한다.
 +
* String substring(int beginIndex, int endIndex) : 인자로 주어진 인덱스 사이의 문자열을 반환한다.
 +
* String toLowerCase() : 소문자로 변경한다.
 +
* String toUpperCase() : 대문자로 변경한다.
 +
* String trim() : 문자열 앞, 뒤의 whitespace를 제거한다.
 +
* static String valueOf(int i) : 인자로 주어진 타를 타입의 데이터를 문자열로 변경하는 정적 매소드다. 모든 원시 타입에 대해 오버로딩된 매소드가 있다.
 +
 
 +
{{각주}}
 +
 
 +
== 참고자료 ==
 +
* 문자열 위키백과 - https://ko.wikipedia.org/wiki/%EB%AC%B8%EC%9E%90%EC%97%B4
 +
* 문자열 네이버 국어사전 - https://ko.dict.naver.com/#/entry/koko/c385391b480e47d7b88c13513f06bde1
 +
* SLL, 〈[https://m.blog.naver.com/PostView.nhn?blogId=sharonichoya&logNo=220488567828&proxyReferer=https%3A%2F%2Fwww.google.com%2F C언어 문자열(string) 기본개념]〉, 《네이버 블로그》, 2015-09-22
 +
* 〈[http://tcpschool.com/c/c_string_string 문자열]〉, 《TCP School》
 +
* OffByOne, 〈[https://offbyone.tistory.com/401 자바 문법 - 문자열(String 객체) 다루기]〉, 《티스토리》, 2019-08-11
 +
* 〈[https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/strings/ 문자열(C# 프로그래밍 가이드)]〉, 《Microsoft》, 2019-06-27
  
 
== 같이 보기 ==
 
== 같이 보기 ==
* [[Java 문자열]]
+
* [[배열]]
* [[C 문자열]]
+
* [[데이터]]
 +
* [[자바]]
 +
* [[C]]
 +
* [[C++]]
 +
* [[클래스]]
 +
* [[변수]]
 +
* [[메서드]]
 +
 
 +
{{프로그래밍|검토 필요}}

2020년 9월 4일 (금) 11:43 기준 최신판

문자열(string)이란 데이터로 다루는 일련의 문자를 의미한다. 문자열은 기호의 순차 수열을 포함하기 때문에 숫자를 포함하는 것이어도 계산하는 숫자로서가 아닌 코드의 일부로 쓰인다면 문자열이라고 할 수 있다.

개요[편집]

일반적으로 문자열은 말 그대로 문자 등을 1차원적으로 나열한 것을 의미한다. 이때 문자의 의미는 말 그대로 문자(character)일 수도 있으나 하나의 계속되는 비트(bit), 레코드(record) 등을 나타낸다. 이들을 각각 문자열(character string), 비트 스트링(bit string), 레코드 스트링(record string)이라고 한다. 문자열에는 하나의 자료를 구성하기 위하여 일련의 문자 집합으로 구성된 정보가 담기게 된다. 프로그래밍에서 문자열은 일반적으로 취급하는 데이터형의 하나로 인식된다. 사용하는 컴퓨터 시스템으로 인식할 수 있으며, 비트 배치를 갖는 문자로 이루어지는 집합에서 취한 0개 이상의 문자로 배열이 이루어진다. 이때 요소는 문자 인코딩과 관련된 문자를 대표하는 일련의 자료값을 저장하고 있는 자료형으로 이해할 수 있다. 여기서 문자 인코딩의 경우 더 일반적인 배열 자료형과 차이가 있다. 이러한 환경에서 이진 문자열(binary string)과 바이트 문자열(byte string)이라는 용어는 저장된 자료가 반드시 텍스트를 표시하지 않아도 되는 문자열을 표시하는 데 사용된다. 문자열 자료형으로 선언된 변수의 경우, 미리 정의된 어느 정도의 기호를 소유할 수 있는 메모리에 기억 자료를 할당하는 것이 보통이다. 문자열이 소스 코드에 보이면 그 문자열을 스트링 리터럴(string literal)이라고 일컫는다.

특징[편집]

char형 변수로 문자열을 저장하기에는 당연히 무리가 따른다. char형 변수는 문자 1개만을 저장하기 위한 변수이기 때문이다. 문자열을 저장하기 위해서는 char형 배열이 필요하다. 예를 들어 5글자의 문자를 저장하고자 한다면 크기가 5인 char형 배열을 생성하여 저장하면 된다. 1바이트(byte) 당 한글자가 저장이 되며 배열의 크기는 지정이 가능하다. 문자열은 이처럼 char형 배열로 저장이 가능하다.[1]

문자상수/문자열상수[편집]

문자상수는 'A'와 같이 작은따옴표(' ')로 표현한다. 상수라고 해서 숫자만 있는 것이 아님을 유의해야 한다. 문자 상수란 문자의 값이며 변하지 않는 수이다. 예를 들어서 'A'라고 하면 이 A는 문자값이다. 하지만 char A; 라고 하면 이 A는 문자값이 아니라 문자를 저장하기 위한 변수다. A라고 하는 이름은 변하지 않지만 그 안에 들어가는 문자상수(값)은 언제든 변할수 있기 때문이다. 유사하게 문자열상수란 문자열값을 의미하며, 큰따옴표(" ")로 표현한다. "Hello", "Be Happy~" 와 같은 것들이 문자열상수이다.[1] C 언어에서는 큰따옴표를 사용해 표현되는 문자열을 문자열 상수(string constant)라고 한다. 상수라고 표현하는 이유는 해당 문자열이 이름을 가지고 있지 않으며, 문자열의 내용 또한 변경할 수 없기 때문이다. C언어에서 문자열은 메모리에 저장된 일련의 연속된 문자들의 집합을 의미한다. 따라서 문자형 배열을 선언하면 이 배열이 곧 문자열 변수가 된다.[2] 문자열에 대한 예를들면 'A'는 문자이지만, 'ABCD'는 문자열이다. 즉 문자가 여러개 모인것을 지칭한다. 문자는 char형 변수에 저장이 된다. 간단한 코드로 보면,

char a = 'A';
char b = 'D';

와 같이 저장하면 된다. char형은 1바이트로 할당되며 문자는 1바이트로 저장이 가능하다는 말이다.

문자열의 초기화[편집]

문자열을 초기화하기 위한 방법은 세 가지로 나뉜다.

char str[6]= { 'H', 'e', 'l', 'l', 'o'. '\0'};

char str[6]= "Hello";

char str[]= "Hello";

A는 크기가 6인 문자배열을 선언하고 각 자리에 들어갈 문자를 순서대로 지정해주는 것이다. B는 크기가 6인 문자배열을 선언함과 동시에 문자열을 대입하는 방법이다. 큰따옴표로 표현해주면 되겠다. 주의할점은 크기가 6이므로 이 크기를 벗어나는 문자열상수는 초기화할 수 없다. C는 문자열상수로 초기화하지만 배열의 크기를 지정하지 않는다. 이런 경우 문자열상수의 크기에 따라 자동으로 str배열의 크기를 지정해주게 된다. C가 문제도 없고 가장 편해보이지만, 문자열이 긴 경우에 개발자가 그 크기를 직접 계산해서 알고 있어야 한다는 불편함이 따른다. 직관적으로 크기도 알고 문자열도 알수 있는 B가 가장 무난하다고 생각할 수 있겠다.[1]

문자열의 출력[편집]

저장한 문자열을 출력에 대해 printf 함수만을 예로 들어 설명하면, printf 함수를 사용할 때 출력되는 형태를 지정하기 위해서 형식지정 문자 또는 서식문자 라고 불리는 %로 시작하는것을 붙인다. 예를 들어 %d는 십진수정수 형태로 출력하라는 %x는 16진수, %lf는 double형타입, %o, %u 등등 여러 가지가 지정되어 있다. 문자는 %c로 출력하고, 문자열은 %s로 출력하면 된다.[1]

char c ='A';

char str[10]= "ILoveYou"; 

이제 출력하려면,

printf("%c", c);

printf("%s", str);

%s로 지정을 하면되는데, 이에 대응되는 변수부분이 str 즉 배열의 이름이 된다. 그런데 str은 배열의 이름이고, 배열의 이름은 바로 이 배열 전체를 대표하는 이름이자 첫번째 주소값을 가지고 있는 포인터의 성질을 갖는다. printf도 함수이니 str은 함수의 매개변수가 된다. printf 함수가 문자열을 출력할 때 이 문자열이 저장되어 있는 가장 첫 번째 주소값을 주면 출력해준다는 사실을 알 수 있다. 즉 %s를 이용해 문자열을 출력할때 이에 대응되는 우측부분에 들어가는 데이터의 타입은 바로 char* 이다.[1]

NULL 문자('\0')[편집]

(NULL)이라는 문자는 상징적으로 사용되며 사실상 그 값은 0이다. 문자는 역슬래쉬0 = \0으로 표현한다. 문자열은 항상 마지막 공간에 널 문자 1개를 포함하고 있다. 만약 'ILoveYou'를 저장하고 싶다면 실제 문자는 8개지만 마지막에 널문자가 추가되어 있어야만 한다. 초기화 방법에서 A는 각 메모리공간 하나하나를 지정하고 있기때문에 반드시 마지막에 널문자를 넣어주어야 한다. B와 C같은 경우는 문자열 상수로 초기화되므로 자동으로 들어가게 된다. 즉, 보이지 않지만 분명 1바이트를 차지하고 있는 널문자가 존재하고 있는 것이다. 따라서 char형 배열에 문자를 저장하고 싶다면 반드시 문자의 갯수 + 1에 해당하는 크기를 할당해 놓아야 제대로 된 저장이 가능하다.[1] 문자형 배열로 선언된 문자열 변수는 문자열의 끝을 프로그램에 따로 알려주어야 한다. 그래야만 프로그램이 실제 문자열에 속한 값과 그 외의 쓰레깃값을 구분할 수 있기 때문이다. 따라서 C 언어에서는 문자열에 속한 데이터가 끝나면, 문자열의 끝을 의미하는 문자를 하나 더 삽입해 준다. 이 문자를 널 문자라고 하며, '\0'으로 표시하고 아스키코드값은 0이다.[2]

문자열 이스케이프 시퀀스[편집]

이스케이프 시퀀스 문자 이름 유니코드 인코딩
\' 작은따옴표 0x0027
\" 큰따옴표 0x0022
\\ 백슬래시 0x005C
\0 Null 0x0000
\a 경고 0x0007
\b 백스페이스 0x0008
\f 폼 피드 0x000C
\n 줄 바꿈 0x000A
\r 캐리지 리턴 0x000D
\t 가로 탭 0x0009
\v 세로 탭 0x000B
\u 유니코드 이스케이프 시퀀스(UTF-16) \uHHHH (범위: 0000-FFFF; 예제: \u00E7 “ç” =)
\U 유니코드 이스케이프 시퀀스(UTF-32) \U00HHHHHH (범위: 000000-10FFFF; 예: \U0001F47D = “👽”)
\x 길이가 변하는 경우를 제외하고 “\u”와
유사한 유니코드 이스케이프 시퀀스한다.
\xH[H][H][H] (범위: 0-FFFF; 예: \x00E7 나 \x0E7 또는 \xE7 "ç" =)
이스케이프 시퀸스[3]

형식 문자열[편집]

형식 문자열은 콘텐츠가 런타임에 동적으로 결정되는 문자열이다. 형식 문자열은 문자열 내의 중괄호 안에 ‘보간된 식’이나 자리 표시자를 포함하여 만들어진다. 중괄호({...}) 안의 모든 내용은 런타임에 하나의 값으로 확인되고 형식화된 문자열로 출력된다. 형식 문자열을 만드는 두 가지 방법은 문자열 보간 및 복합 형식 지정이다.[3]

문자열 보간[편집]

C# 6.0 이상에서 사용 가능한 ‘보간된 문자열’은 $ 특수 문자로 식별되고 중괄호 안에 보간된 식을 포함한다. 코드의 가독성과 유지 관리를 개선하려면 문자열 보간을 사용한다. 문자열 보간은 String.Format 매소드와 동일한 결과를 제공하지만 더 편리하고 인라인 명확성이 향상된다.[3]

복합 형식 지정[편집]

String.Format은 중괄호 안에 자리 표시자를 활용하여 형식 문자열을 만든다. 이 예제는 위에서 사용한 문자열 보간 방법과 유사한 출력을 생성한다.

부분 문자열[편집]

부분 문자열은 문자열에 포함된 임의의 문자 시퀀스다. 원래 문자열 일부에서 새 문자열을 만들려면 서브스트링(Substring) 매소드를 사용해야 한다. 인덱스오브(IndexOf) 매소드를 사용하면 부분 문자열 항목을 하나 이상 검색할 수 있다. 지정된 부분 문자열의 모든 항목을 새 문자열로 바꾸려면 리플레이스(Replace) 매소드를 사용한다. 서브스트링 매소드와 마찬가지로, 리플레이스는 실제로 새 문자열을 반환하며, 원래 문자열은 수정되지 않는다.[3]

개별 문자 액세스[편집]

문자열에서 개별 문자를 수정해야 하는 기능이 스트링(String) 매소드에서 제공되지 않는 경우에는 스트링빌더(StringBuilder) 개체를 사용하여 개별 문자를 "현재 위치"에서 수정한 후 새 문자열을 만들어 스트링빌더 매소드로 결과를 저장할 수 있다.[3]

자바 문자열[편집]

자바(Java) 문자열은 객체이고 문자열 리터를은 큰 따옴표로 묶어 표시한다. 문자열 리터럴도 객체이므로 바로 매소드를 호출할 수 있다.[4]

문자열 연결[편집]

자바 문자열을 연결하는데는 + 연산자를 사용한다.

String h = "Hello ";
String j = "Java!";

String text = h + j;

System.out.println(text);
결과)
Hello Java!

자바에서 문자열에 연산을 사용하는데 있어서 주의해야 할 점이 있는데, 자바 문자열은 불변(immutable)이라는 점이다. 문자열에 연산을 가하면 현재 문자열을 변경되지 않고 변경된 새 문자열이 만들어져서 반환된다.[4]

String h = "Hello Java!";
String t = h.substring(0, 5);

System.out.println(h);
System.out.println(t);
결과)
Hello Java!
Hello

많은 문자열을 연결할 경우에는 성능문제로 인해 + 연산자 보다는 스트링빌더(StringBuilder) 객체를 사용한다. 이전에는 스트링빌더 객체를 사용했었는데, JDK 1.5 부터 스트링빌더 객체가 나와서 이것을 사용한다. 스트링버퍼(StringBuffer)와 스트링빌더 객체의 차이점은 스트링버퍼 객체의 매소드는 싱크로나이즈드(synchronized) 되어 있어서 다중 쓰레드에서 안전하고, 스트링빌더는 싱크로나이즈드 되어 있지 않아 다중 쓰레드 환경에서는 사용할 수 없지만 싱글 쓰레드 환경에서 동기화 오버헤드가 없으므로 더 빠르게 동작한다. 그래서 대부분의 경우 스트링빌더를 사용한다.[4]

문자열 비교[편집]

String 객체를 비교할 때는 equals() 매소드를 사용한다. 기본 타입이 같은지 비교할때 사용되는 == 연산자를 사용하여 객체를 비교하게 되면 객체가 존재하는 메모리상의 주소가 같은지를 비교하게 되어서 잘못된 결과를 보게 될 것이다. 객체인 스트링(String)을 비교할 때는 equals() 매소드를 사용한다.[4]

String h = "Hello ";
String j = "Java!";

if(h.equals(j)) {

   System.out.println("h와 j는 같은 내용을 가지는 문자열 입니다.");

}

문자열을 특정 문자열 리터럴과 비교할 경우가 있다. 이 경우 "".equals() 처럼 비교하고자 하는 리터럴의 매소드를 사용하는것이 안전하다. 아래처럼 사용할 경우 h가 null이면 NullPointerException이 발생할 수 있다.

if("Hello".equals(h)) {
   ...
}

문자열을 사전순으로 정렬했을때의 우선 순위를 비교하려면 compareTo() 매소드를 사용한다.

String year = "2018"
int result = "2019".compareTo(year);

if(result > 0) {
   // 현재 년도 보다 큼
} else if(result == 0) {
   // 현재 년도와 같음.
} else if(result < 0) {
   // 현재 년도 보다 작음
}

문자열 매소드[편집]

자주 사용하는 문자열의 매소드들은 아래와 같다.[4]

  • char charAt(int index) : 지정된 인덱스의 한 문자를 반환한다.
  • int compareTo(String anotherString) : 두 문자열의 사전적 우선 순위 비교
  • int compareToIgnoreCase(String str) : 대소문자를 구분하지 않는 사전적 비교
  • boolean contains(CharSequence s) : 문자열을 포함하고 있는지 확인한다.
  • boolean endsWith(String suffix) : 문자열의 끝이 인자로 주어진 문자열인지 확인한다.
  • boolean equals(Object anObject) : 같은 내용의 문자열인지 비교한다.
  • boolean equalsIgnoreCase(String anotherString) : 대소문자를 구분하지 않고 비교한다.
  • byte[] getBytes() : 플랫폼 기본 캐릭터셋으로 인코딩된 바이트 배열을 링크한다.
  • byte[] getBytes(String charsetName) : 인자로 주어인 캐릭터 셋으로 인코딩된 바이트 배열을 반환한다. 캐릭터셋을 변환하기 위해서 주로 사용됌.
  • int indexOf(int ch) : 인자로 주어진 문자가 있는 위치를 반환한다. 없으면 음수를 반환한다.
  • boolean isEmpty() : 빈문자열 인지 확인한다.
  • int lastIndexOf(int ch) : 인자로 주어진 문자가 마지막으로 나타난 위치를 반환합니다. 없으면 음수를 반환한다.
  • int length() : 문자열의 길이를 반환한다.
  • boolean matches(String regex) : 인자로 주어진 정규식에 매치되는지 확인한다.
  • String replace(char oldChar, char newChar) : 문자열에서 첫번째 인자의 문자를 두번째 인자의 문자로 바꾼다.
  • String replace(CharSequence target, CharSequence replacement) : 문자열을 바꾼다.
  • String replaceAll(String regex, String replacement) : 정규식을 사용하여 매치되는 문자열을 바꾼다.
  • String[] split(String regex) : 정규식에 매치되는 부분을 구분자로 문자열을 분할한다.
  • String[] split(String regex, int limit) : 문자열 분할시 두번째 인자로 마지막 빈 요소 처리 및 분할할 갯수를 지정한다.
  • boolean startsWith(String prefix) : 인자로 주어진 문자열로 시작하는지 확인한다.
  • String substring(int beginIndex) : 문자열에서 인자로 주어인 인덱스 이후의 문자열을 추출한다.
  • String substring(int beginIndex, int endIndex) : 인자로 주어진 인덱스 사이의 문자열을 반환한다.
  • String toLowerCase() : 소문자로 변경한다.
  • String toUpperCase() : 대문자로 변경한다.
  • String trim() : 문자열 앞, 뒤의 whitespace를 제거한다.
  • static String valueOf(int i) : 인자로 주어진 타를 타입의 데이터를 문자열로 변경하는 정적 매소드다. 모든 원시 타입에 대해 오버로딩된 매소드가 있다.

각주[편집]

  1. 1.0 1.1 1.2 1.3 1.4 1.5 SLL, 〈C언어 문자열(string) 기본개념〉, 《네이버블로그》, 2015-09-22
  2. 2.0 2.1 문자열〉, 《TCP School》
  3. 3.0 3.1 3.2 3.3 3.4 문자열(C# 프로그래밍 가이드)〉, 《Microsoft》, 2019-06-27
  4. 4.0 4.1 4.2 4.3 4.4 OffByOne, 〈자바 문법 - 문자열(String 객체) 다루기〉, 《티스토리》, 2019-08-11

참고자료[편집]

같이 보기[편집]


  검수요청.png검수요청.png 이 문자열 문서는 프로그래밍에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.