[Cocoa / Objective-C] NSString의 문자열 뒤집기, 글자를 정렬한 문자열 구하기.

프레임워크에 당연히 있는 기능일 줄 알았는데 없더라… 그래서 자작.

짤막한 설명

문자열 뒤집기는 C문자열로 바꾼다음 포인터를 쓰는게 제일 깔끔할 것 같아서 그렇게 했다. -UTF8String 메소드는 const char 타입 포인터를 리턴하는데, 이걸 char 형으로 강제캐스팅하는 게 찜찜해서 strcpy로 복사했는데, 어디서 이 함수도 상당히 나쁘다고 쓰지 말라더라. (다른 뭐를 쓰라던데 그게 기억이 안나서 그냥 씀)

malloc으로 할당한 메모리는 ARC의 관심밖이므로 철저히 free 해주는 나란 남자, 그런 남자…

문자열내 문자들을 사전순으로 정렬해주는 건 소인수 분해 따위나 할 때 쓸모가 있긴 있을텐데,  NSArraysortedUsingComparator: 메소드를 사용했다.  OSX에서는 코드 블럭( ^( ){ … } )을 쓰면 되는데 GNUStep에서는 이게 함수포인터를 쓰는 것 같더라. 아마 이 코드 그대로 쓰면 안될 듯. GNUStep의 정렬 메소드는 함수 포인터로 되어 있고 아예 메소드명이 달라서, NSSortDescriptor를 사용하는 방법으로 변경했다. 지난 번 버전의 코드는 여기에서 볼 수 있다.

함수 내에서 상당히 많은 autorelease 되는 NSString을 만들어낼 수도 있어서, 메소드 안쪽에 autoreleasepool 블럭을 설치해줬다.

 

20110621 :: NSString 사용하기

NSString에서 알아두어야할 몇가지 메소드들을 정리해본다.

문자열 생성

포맷에 맞게 문자열을 생성하기

+stringWithFormat: 메소드를 사용한다.

NSString *newStr = [NSString stringWithFormat:@"%@ : %d", someObj.name, someObj.score];

-initWithFormat:의 경우 같은 동작을 하지만, 이 때는 수동으로 alloc하므로 릴리즈의 책임을 져야 한다.

C문자열로부터 생성

initWithUTF8String:, stringWithUTF8String: 을 통해서 const char* 데이터를 NSString 객체로 바꿀 수 있다. 1

다른 인코딩을 된 문자열이라면 initWithCString:encoding:, stringWithCString:encoding:을 사용할 수 있다.

바이너리 데이터로부터 생성

NSData(파일을 읽어들였거나, 네트워크 스트림으로부터 받은)객체로도 이를 만들 수 있다. initWithData:encoding:을 쓴다. 특히 파일의 경우, stringWithContentsOfFile:encoding:error:stringWithContentsOfURL:encoding:error:를 쓸 수 있다.

파일에 쓰기

-writeToFile:atomically:encoding:error:이 가장 기본적인 파일 쓰기 함수이다. URL 베이스의 -writeToURL:atomically:encoding:error:도 있다. 미리 파일을 열고 닫을 필요가 없다.

속성

길이구하기

-length 프로퍼티를 이용한다. 이는 유니코드 문자의 개수를 돌려주는데, 만약 특정 인코딩으로 변환한 후의 데이터 크기를 알고 싶다면 -lengthOfBytesUsingEncoding:을 쓴다.

서브스크립트

특정 위치의 글자는 characterAtIndex:로 구한다. (반환형은 unichar로 유니코드 문자 한 개의 값이다.) 서브 스트링을 구할 때는 getCharacters:range:를 쓴다. 이는 NSString을 돌려주는게 아니라 unichar* 타입의 포인터를 받아서 range만큼 뽑아 복사해준다.

NSString 객체로 된 서브스트링을 얻으려면 substringWithRange:substringFromIndex:, substringToIndex:를 쓴다.

C 문자열 얻기

UTF8String 속성을 사용한다. 별도 인코딩을 쓰려면 cStringUsingEncoding:을 쓴다.

문자열 결합하기

문자열의 배열을 하나로 join 하는 것은 NSArray의 componensJoinedByString:을 사용하면 된다. 그외 다른 문자열을 결합하기위해서는 stringByAppendingString: 이나 stringByAppendingFormat:을 쓴다. (한번 생성된 문자열은 내부 데이터를 변경할 수 없으므로 새로운 문자열을 만들어야 한다.)

문자열 나누기

문자열을 특정 토큰으로 나누어 배열로 만드려면 componentsSeparatedByString: 이나 componentsSeparatedByCharactersInSet:을 이용한다.

문자열 내에서 특정 문자/문자열 찾기

가장 많이 쓰이는 것은 rangeOfString:이다.

문자열 바꾸기

서브스트링 치환은 stringByReplacingOccurrencesOfString:withString:이다. 추가로 범위나 옵션 제한을 두는 stringByReplacingOccurrencesOfString:options:range:도 있다. 그냥 특정 범위를 다른 문자열로 바꾸는 stringByReplacingCharactersInRange:withStirng:도 있다.

프로퍼티리스트 변환

프로퍼티 리스트 파싱을 자동으로 할 수 있다. propertyList, propertyListFromStringsFileFormat 문자열을 프로퍼티리스트로 파싱하면 사전 객체를 리턴해준다.

비교

정렬을 위해서 비교 구문을 쓴다. compare:는 합성글리프에 대한 연산이 정확하지 않으므로 localizedCompare:localizedCaseInsentiveCompare:를 많이 쓴다. 비교 함수의 결과는 NSComparisonResult로 이는 NSOrderAscending | NSOrderEqual | NSOrderDescending중 하나가 된다.

케이스 변환

capitalizedString, lowercaseString, uppercaseString 등이 있다.

숫자값

문자열 내용이 숫자인 경우 intValue, floatValue… 등의 즉시 변환 함수가 있다.

그외 다음 기능들이 있는데, 다 못적겠다….
* URL:
* 퍼센트로 인코딩하기
* file path:
* 파일 경로 구분자 추가/확장하기
* 확장자 확장


  1. initWithCString:, stringWithCString: 이라는 메소드가 있었지만, 없어졌다. 대신 인코딩방식을 주는 것은 가능하다.