검색결과 리스트
string에 해당되는 글 2건
- 2015.09.02 [swift2] Swift2에서의 문자열(strings)
- 2011.04.29 문자열 조작함수 직접 구현하기 (2)
글
[swift2] Swift2에서의 문자열(strings)
다음 포스트는 애플 공식 Swift 블로그의 Strings in Swift2 포스트를 번역했습니다.
Swift는 표준 라이브러리의 일부분으로, 성능이 뛰어나고 유니코드와 호환되는 String 구현을 제공합니다. Swift2에서, String 타입은 더이상 CollectionType 프로토콜을 구현하지 않습니다. (이전에는 String은 배열과 유사한 Character 값의 컬렉션이었습니다.) 이제 String은 character 컬렉션을 제공하는 characters 프로퍼티를 제공합니다.
무엇이 바뀌었을까요?
문자들의 컬렉션이 자연스러운 모델이지만, String 타입은 Array, Set, Ditionary와 같은 컬렉션 타입과 꽤 다르게 동작합니다. Swift2에서 프로토콜 extension이 추가되면서 몇몇 변경사항이 생겼습니다.
부분의 합과 다릅니다.
컬렉션에 엘리먼트를 추가하면, 컬렉션은 그 엘리먼트를 포함할 것이라 기대할수 있습니다. 즉 배열에 값을 추가하면, 배열은 그 값을 포함합니다. 동일한 규칙이 dictionary와 Set에도 적용됩니다. 그러나 string에 결합마크 문자를 추가하면 string 자체의 내용이 변합니다.
4개의 문자를 갖는 문자열 cafe를 예를 들어보겠습니다.
var letters: [Character] = ["c", "a", "f", "e"]
var string: String = String(letters)
print(letters.count) // 4
print(string) // cafe
print(string.characters.count) // 4
만일 악센트 문자 U+0301 ´를 결합하면, 문자열은 그대로 4글자 이지만 마지막 문자는 이제 é 입니다.
let acuteAccent: Character = "\u{0301}" // ´ COMBINING ACUTE ACCENT' (U+0301)
string.append(acuteAccent)
print(string.characters.count) // 4
print(string.characters.last!) // é
string의 characters 속성은 오리지널 소문자 e를 포함하지도 않고, 이전에 추가됐던 악센트 문자 ´도 포함하지 않습니다. string은 이제 악센트가 붙은 소문자 "e" 즉 é를 포함합니다.
string.characters.contains("e") // false
string.characters.contains("´") // false
string.characters.contains("é") // true
만일 다른 컬렉션처럼 string을 다룬다면 결과는 Set에 UIColor.redColor() 과 UIColor.greenColor()를 추가하면 set은 UIColor.yellowColor() 포함한다고 리포트하는 것만큼 놀라울 것입니다.
문자의 내용에 따라 결정됩니다.
string과 collection의 또 다른 차이점은 동등성을 판단하는 방법입니다.
- 두 배열은 엘리먼트의 개수가 같고, 대응하는 인덱스에 각 엘리먼트 쌍이 동일하면 동등합니다.
- 두 집합은 엘리먼트의 개수가 같고, 첫 번째 집합에 포함된 각 엘리먼트가 두 번째 집합에도 포함되어 있을때 동등합니다.
- 두 사전은 같은 키,값 쌍을 가지고 있을때 동일합니다.
그러나 String은 canonically equivalent 에 기초하여 동등성이 결정됩니다. 문자는 같은 언어적 의미와 외형을 가진다면 다른 유니코드 스칼라로 구성되어 있다하더라도 cannonically 동등합니다.
canonically equivalent: 유니코드 문자 인코딩 표준에 정의된 스펙. 코드포인트 순서집합이 출력되었을 때, 같은 외형과 의미를 갖을때 canonically equivalent 하다고 표현합니다.
자음과 모음을 나타내는 24개의 문자로 구성된 한국어 표기법을 예로 들어보겠습니다. 표기할때 각 문자들은 각 음절이 결합하여 글자를 이룹니다. 예를 들어 글자 '가'는 문자 'ㄱ' 과 'ㅏ' 로 구성됩니다. Swift에서는 String은 조합형인지 완성형인지에 상관없이 동등성을 판단합니다.
let decomposed = "\u{1100}\u{1161}" // ᄀ + ᅡ
let precomposed = "\u{AC00}" // 가
decomposed == precomposed // true
즉 String은 다른 Swift 컬렉션 타입의 어떤것들과도 완전 다르게 동작합니다. 🐟과 🍚 값으로 구성된 배열이 🍣과 동등하다고 여겨진다면 매우 놀라울 것입니다.
당신의 관점에 달려있습니다.
string은 collection이 아닙니다. 대신 string은 CollectionType 프로토콜을 따르는 뷰들을 제공합니다.
- characters는 Character 값 또는 extended grapheme cluster의 컬렉션입니다.
- unicodeScalars 는 유니코드 스칼라 값들의 컬렉션입니다.
- utf8는 UTF-8 코드 유닛의 컬렉션입니다.
- utf16은 UTF-16 코드 유닛의 컬렉션입니다.
extended grapheme cluster: 유니코드 스칼라 묶음이 조합되었을 때, 사람이 읽을 수 있는 문자가 되는 구성.
이전이 예제에서 단어 café 는 [ c, a, f, e ] 와 [ ´ ] 로 구성되어 있으며, string의 다양한 뷰들은 아래와 같습니다.
characers 속성은 사용자가 인식하는 문자인 extended grapheme clusters로 분리합니다. string은 문자열 내부에서 문자 경계를 결정하기 위해 코드 포인트라고 하는 각 위치를 순회해야 하기 때문에, 이 속성에 대한 접근은 O(n) 시간이 걸립니다. 인간이 읽을수 있는 텍스트를 포함하는 문자열을 처리할 때, localizedStandardCompare(_:) 메서드나 localizedLowercaseString 속성에서 사용되는 하이레벨 locale-sensitive 유니코드 알고리즘들에서 문자단위 처리가 자주 사용됩니다.
unicodeScalars 속성은 문자열에 저장된 내부의 스칼라 값을 노출합니다. 만일 원래 문자열이 조합형 e + ´ 로 구성되지 않고 완성형 é로 생성되었다면, 이런 구성이 유니코드 스칼라뷰에 반영됩니다. 문자 데이터의 low-level 조작을 수행할때 이 API를 사용하세요.
utf8과 utf16 속성들은 UTF-8과 UTF-16 표현에 대한 코드포인트를 제공합니다. 이 값들은 특정 인코딩으로부터 혹은 인코딩으로 변환할때 파일에 쓰여지는 실제 바이트에 대응합니다. UTF-8 코드 유닛은 많은 POSIX 문자열 처리 API에서 사용되며, UTF-16 코드 유닛은 문자열의 길이와 오프셋을 표현하기 위해 Cocoa & Cocoa Touch에서 전반적으로 사용됩니다.
'Swift' 카테고리의 다른 글
| [swift] Swift 코딩환경 Playground (0) | 2015.10.05 |
|---|---|
| [swift2] Swift Guard (0) | 2015.09.11 |
| [swift2] Swift2에서의 문자열(strings) (0) | 2015.09.02 |
| [swift2] Xcode7 beta6 Swift 언어 변경사항 (0) | 2015.08.27 |
| [swift2] Xcode7 beta5 Swift 언어 변경사항 (0) | 2015.08.14 |
| [swift1.2] Swift 프로토콜 지향 프로그래밍 (0) | 2015.08.06 |
설정
트랙백
댓글
글
문자열 조작함수 직접 구현하기
string.h 에서 지원하는 문자열 조작 함수들을 직접 구현해보았다. 이 함수들은 이름에 'str' 이라는 접두어를
1. 문자열 함수들의 프로토 선언과 기능
- // 문자열 s의 길이를 반환하는 함수
int strlen(char *s);
// s에 문자열 t를 복사하는 함수- void strcpy(char *s, char *t);
- // 두 문자열을 비교하는 함수 : 같으면 0, 앞문자열이 크면 양수, 작으면 음수반환
- int strcmp(char *s, char *t);
// 문자열 dest의 끝에 src 문자열을 연결하는 함수
- char *strcat(char *dest, const char *src)
- // 문자열 string에서 문자 c를 찾아 위치를 반환하는 함수. 없으면 NULL 반환
- char *strchr(const char *string, int c);
- // 문자열 string의 끝에서부터 문자 c를 찾아 위치를 반환하는 함수. 없으면 NULL 반환
- char *strrchr(const char *string, int c);
- // 문자열 string에서 문자열 strSearch를 찾아 첫번째 위치를 반환. 없으면 NULL 반환
- char *strstr(const char *string, const char *strSearch);
- // 문자열 string에서 strCharSet문자열에 속한 문자가 발견되면 그 위치를 반환. 없으면 NULL 반환
- char *strpbrk(const char *string, const char *strCharSet);
- // 문자열 str에서 delims 문자열에 속한 문자를 구분자로 분리해주는 함수. 첫번째 호출후
- // NULL 을 주어 호출하면, 기존 문자열에서 계속 구분자를 기준으로 분리해서 반환해줌// 원 문자열을 변경하기 때문에 원치않다면 원문자열의 복사본을 사용해야 한다.
- char *strtok(char *str, const char *delims);
2. 문자열 조작 함수의 구현
#include <string.h>
int my_strlen(char *s);
void my_strcpy(char *s, char *t);
int my_strcmp(char *s, char *t);
char *my_strcat(char *dest, const char *src);
char *my_strncat(char *dest, const char *src,size_t count);
char *my_strchr(const char *string, int c);
char *my_strrchr(const char *string, int c);
char *my_strstr(const char *string, const char *strSearch);
char *my_strpbrk(const char *string, const char *strCharSet);
char *my_strtok(char *str, const char *delims);
int main (int argc, char const* argv[])
{
char dest[1024] = "nice to meet you!";
char *test = "my name is kimsungbae! what's up?";
char *token;
printf("strchr : %s \n", strchr(test, '!'));
printf("my_strchr: %s \n", my_strchr(test, '!'));
printf("\n");
printf("strrchr : %s \n", strrchr(test, '\''));
printf("my_strrchr: %s \n", my_strchr(test, '\''));
printf("\n");
printf("strstr : %s \n", strstr(test, "is"));
printf("my_strstr: %s \n", my_strstr(test, "is"));
printf("\n");
printf("my_strcat : %s \n", my_strcat(dest, test));
printf("my_strncat: %s \n", my_strncat(dest, "@@@@@@@@", 2));
printf("\n");
printf("strpbrk : %s \n", strpbrk(test, "?!\'"));
printf("my_strpbrk : %s \n", my_strpbrk(test, "?!\'"));
token = my_strtok(dest, " ");
printf("%s \n", token);
while ((token = my_strtok(NULL, " ")) != NULL) {
printf("%s \n", token);
}
return 0;
}
int my_strlen(char *s) {
char *p = s;
while (*p++ != '\0');
return p - s;
}
void my_strcpy(char *s, char *t) {
while (*s++ = *t++) ;
}
int my_strcmp(char *s, char *t) {
for (; *s == *t; s++, t++) {
if (*s == '\0') {
return 0;
}
}
return *s - *t;
}
char *my_strcat(char *dest, const char *src) {
char *p_dest = dest;
while (*p_dest != '\0') {
p_dest++;
}
while (*src != '\0') {
*p_dest++ = *src++;
}
*p_dest = '\0';
return dest;
}
char *my_strncat(char *dest, const char *src,size_t count) {
char *p_dest = dest;
while (*p_dest != '\0') {
p_dest++;
}
while (*src != '\0' && count > 0) {
*p_dest++ = *src++;
count--;
}
*p_dest = '\0';
return dest;
}
char *my_strchr(const char *str, int c) {
while (*str != '\0') {
if (*str == c) {
return str;
}
str++;
}
return NULL;
}
char *my_strrchr(const char *str, int c) {
char *p_str = str + strlen(str) - 1;
while (p_str > str) {
if (*p_str == c) {
return p_str;
}
p_str--;
}
return NULL;
}
char *my_strstr(const char *str, const char *search) {
char *start = NULL;
while (*str != '\0') {
if (start != NULL && *search == '\0') {
break;
}
if (start != NULL && *str != *search) {
start = NULL;
}
if (start == NULL && *str == *search) {
start = str;
}
if (start != NULL && *str == *search) {
search++;
}
str++;
}
return (start != NULL) ? start : NULL;
}
char *my_strpbrk(const char *str, const char *charset) {
char *p_char;
while (*str != '\0') {
p_char = charset;
while (*p_char != '\0') {
if (*str == *p_char++) {
return str;
}
}
str++;
}
return NULL;
}
char *my_strtok(char *str, const char *delims) {
static char *tmp, *pstart;
char *p_delims;
if (str != NULL) {
tmp = str;
}
if (*tmp == '\0') {
return NULL;
}
pstart = tmp;
while (*tmp != '\0') {
p_delims = delims;
while (*p_delims != '\0') {
if (*tmp == *p_delims++) {
*tmp++ = '\0';
return pstart;
}
}
tmp++;
}
return pstart;
}
'언어로그 > C/C++' 카테고리의 다른 글
| 과제 #1 입출력,연산자 (0) | 2011.06.13 |
|---|---|
| 음수의 표현 (0) | 2011.06.13 |
| 문자열 조작함수 직접 구현하기 (2) | 2011.04.29 |
| 라인 입출력 함수 (0) | 2011.03.27 |
| 배열의 이해 (0) | 2011.03.27 |
| 기억부류(Storage Class) / 변수 (0) | 2011.03.27 |
my_string.c