当C++遇到iOS应用开发:字符串处理篇

移动开发 iOS
X-Code提供了自动配对“[]”号的功能,但一阅读起源代码后依旧让人心生厌恶。给人一种“强迫打字综合症”的感觉。所以我在NSMutableString基础上用C++进行了封装,特别是对于一些常用方法的使用,在使用时会非常方便,与C#没太大差别。

在 Object-c中,字符串处理通常使用NSString,NSMutableString这两个类,前者用于定长字符串,后者用于可变长度字符串的操 作。尽量其提供的方法很丰富,但一用起来后就让人感到很难受,比如其超长的方法名称(如 stringByReplacingPercentEscapesUsingEncoding),再加上嵌套“[]”式的调用方式,让人很快就会产生" []"匹配综合症。

即使X Code提供了自动配对“[]”号的功能,但一阅读起源代码后依旧让人心生厌恶。给人一种“强迫打字综合症”的感觉。所以我在NSMutableString基础上用C++进行了封装,特别是对于一些常用方法的使用,在使用时会非常方便,与C#没太大差别。

首先看一下String类的源码(说明:因为C++中有std::string这个类,为了与其区别,这里使用了首字母大写)。

  1. #import "RegexKitLite.h" 
  2. #define RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; } 
  3. class String { 
  4. private
  5. NSMutableString *temp; 
  6. static inline NSMutableString* ToMutableString(NSString *str){ 
  7. return [[NSMutableString stringWithString:(NSString *)str] autorelease]; 
  8. public : 
  9. String(){ 
  10. temp = ToMutableString(@""); 
  11. String(NSString *str){ 
  12. temp = ToMutableString(str); 
  13. String(int value){ 
  14. temp = ToMutableString([NSString stringWithFormat:@"%d", value]); 
  15. String(float value){ 
  16. temp = ToMutableString([NSString stringWithFormat:@"%f", value]); 
  17. String(std::string str){ 
  18. temp = ToMutableString(toNSString(str)); 
  19. String(const char* str){ 
  20. temp = ToMutableString(toNSString(str)); 
  21. ~String(){ 
  22. RELEASE_SAFELY(temp); 
  23. NSString * toString(){ 
  24. return temp; 
  25. const std::string toStdString(){ 
  26. return [temp UTF8String]; 
  27. NSString * toLower(){ 
  28. return [temp lowercaseString]; 
  29. NSString* toUpper(){ 
  30. return [temp uppercaseString]; 
  31. int length(){ 
  32. return temp.length; 
  33. bool contains(NSString *search){ 
  34. return [temp rangeOfString:search].location != NSNotFound; 
  35. //不考虑大小写 
  36. static BOOL stringEquals(NSString* str1, NSString* str2) 
  37. if ( str1 == nil || str2 == nil ) { 
  38. return NO; 
  39. return [str1 compare:str2 options:NSCaseInsensitiveSearch] == NSOrderedSame; 
  40. //区分大小写 
  41. static BOOL caseEquals(NSString* str1, NSString* str2) 
  42. return (str1 == nil || str2 == nil) ? NO : [str1 isEqualToString:str2]; 
  43. bool operator==( NSString *str) 
  44. return caseEquals(this->toString(), str); 
  45. bool operator==( String *str) 
  46. return caseEquals(this->toString(), str->toString()); 
  47. //区分大小写 
  48. BOOL startWith(NSString *prefix){ 
  49. if ( temp != nil && prefix != nil ){ 
  50. if ( prefix.length > temp.length ) { 
  51. return NO; 
  52. if ([temp hasPrefix:prefix]){ 
  53. return YES; 
  54. return NO; 
  55. //区分大小写 
  56. BOOL endWith(NSString* suffix){ 
  57. if ( temp != nil && suffix != nil ){ 
  58. if ( [suffix length] > [temp length] ) { 
  59. return NO; 
  60. if ([temp hasSuffix:suffix]){ 
  61. return YES; 
  62. return NO; 
  63. String& operator=( NSString *str) 
  64. temp = ToMutableString(str); 
  65. return (*this); 
  66. String& operator=( std::string str) 
  67. temp = ToMutableString(toNSString(str)); 
  68. return (*this); 
  69. String& operator=( Json::Value value) 
  70. temp = ToMutableString(toNSString(value.asString())); 
  71. return (*this); 
  72. //不区别大小写 
  73. BOOL isURL(){ 
  74. if ( [temp length] > 6 ) { 
  75. NSString* prefix = [temp substringToIndex:6]; 
  76. if (stringEquals(prefix, @"http:/") || stringEquals(prefix, @"https:") ) { 
  77. return YES; 
  78. else if (stringEquals(prefix, @"local:")){ 
  79. return YES; 
  80. if (startWith(@"/")){ 
  81. return YES; 
  82. return NO; 
  83. int toInt(){ 
  84. return [temp intValue]; 
  85. int toFloat(){ 
  86. return [temp floatValue]; 
  87. NSDate* toDate(NSString* fmt){ 
  88. return stringToDate(temp, fmt); 
  89. NSArray* split(NSString *schar){ 
  90. return [temp componentsSeparatedByString:schar]; 
  91. String& trim(){ 
  92. temp = ToMutableString([temp stringByTrimmingCharactersInSet:                                                          [NSCharacterSet whitespaceAndNewlineCharacterSet]]); 
  93. return (*this); 
  94. String& append(NSString *appstr){ 
  95. [temp appendString:appstr]; 
  96. return *this
  97. BOOL isEmpty(){ 
  98. return temp == nil || [temp length] == 0; 
  99. String& appendFormat(NSString* formatStr, ...){ 
  100. va_list arglist; 
  101. va_start(arglist, formatStr); 
  102. id statement = [[NSString alloc] initWithFormat:formatStr arguments:arglist]; 
  103. va_end(arglist); 
  104. [temp appendString:statement]; 
  105. [statement release]; 
  106. return *this
  107. String& replace(NSString *oldStr, NSString *newStr){ 
  108. [temp replaceOccurrencesOfString:oldStr 
  109. withString:newStr 
  110. options:0 range:NSMakeRange(0, [temp length])]; 
  111. return *this
  112. String& regexReplace(NSString *regex, NSString *newStr){ 
  113. NSString *tempstr = temp; 
  114. temp = ToMutableString([tempstr stringByReplacingOccurrencesOfRegex:regex withString:newStr]); 
  115. return *this
  116. NSArray* regexMatchs(NSString *regex){ 
  117. return [temp componentsMatchedByRegex:regex]; 
  118. NSArray* regexMatchs(NSString *regex, int capture){ 
  119. return [temp componentsMatchedByRegex:regex capture:capture]; 
  120. BOOL regexIsMatch(NSString *regex){ 
  121. return [temp isMatchedByRegex:regex]; 
  122. NSString * encodeUrl(){ 
  123. NSString *resultStr = temp; 
  124. CFStringRef originalString = (CFStringRef) temp; 
  125. CFStringRef leaveUnescaped = CFSTR(" "); 
  126. CFStringRef forceEscaped = CFSTR("!*'();:@&=+$,/?%#[]"); 
  127. CFStringRef escapedStr; 
  128. escapedStr = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 
  129. originalString, 
  130. leaveUnescaped, 
  131. forceEscaped, 
  132. kCFStringEncodingUTF8); 
  133. if(escapedStr) 
  134. NSMutableString *mutableStr = [NSMutableString stringWithString:(NSString *)escapedStr]; 
  135. CFRelease(escapedStr); 
  136. if (!mutableStr || [mutableStr isKindOfClass:[NSNull class]] || mutableStr.length <= 0) { 
  137. return resultStr; 
  138. // replace spaces with plusses 
  139. [mutableStr replaceOccurrencesOfString:@" " 
  140. withString:@"%20" 
  141. options:0 
  142. range:NSMakeRange(0, [mutableStr length])]; 
  143. resultStr = mutableStr; 
  144. return resultStr; 
  145. NSString * decodeUrl(){ 
  146. return [temp stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 
  147. NSString * toGBK(){ 
  148. NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000); 
  149. NSData *data = [temp dataUsingEncoding:NSUTF8StringEncoding]; 
  150. return [[[NSString alloc] initWithData:data encoding:enc] autorelease]; 
  151. NSString * toUTF8(){ 
  152. return [DZUtils urlEncode:temp stringEncode:NSUTF8StringEncoding]; 
  153. NSData * toNSData(){ 
  154. return [temp dataUsingEncoding:NSUTF8StringEncoding]; 
  155. NSString* subString(int start/*start from 0*/int count){ 
  156. if(start + count <= temp.length) 
  157. return [temp substringWithRange:NSMakeRange(start, count)]; 
  158. return nil; 
  159. NSString* subString(int count){ 
  160. if(count <= temp.length) 
  161. return [temp substringToIndex: count]; 
  162. return nil; 
  163. static NSDate* stringToDate(NSString * string,  NSString* fmt){ 
  164. NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
  165. [formatter setTimeZone:[NSTimeZone defaultTimeZone]]; 
  166. NSString* format = fmt == nil ? @"yyyy-MM-dd'T'HH:mm:ss'Z'" : fmt; 
  167. [formatter setDateFormat:format]; 
  168. NSDate *date = [formatter dateFromString:string]; 
  169. [formatter release]; 
  170. return date; 
  171. static NSString* dateToString(NSDate* date, NSString* fmt){ 
  172. NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
  173. [formatter setTimeZone:[NSTimeZone defaultTimeZone]]; 
  174. NSString* format = fmt == nil ? @"yyyy-MM-dd'T'HH:mm:ss'Z'" : fmt; 
  175. [formatter setDateFormat:format]; 
  176. NSString* dateStr = [formatter stringFromDate:date]; 
  177. [formatter release]; 
  178. return dateStr; 
  179. static NSString* format(NSString* formatStr, ...){ 
  180. va_list arglist; 
  181. va_start(arglist, formatStr); 
  182. id statement = [[[NSString alloc]  initWithFormat:formatStr arguments:arglist] autorelease]; 
  183. va_end(arglist); 
  184. return statement; 
  185. static NSString* toNSString(std::string str){ 
  186. return toNSString(str.c_str()); 
  187. static NSString* toNSString(const char* str){ 
  188. return [NSString stringWithUTF8String:str]; 
  189. static NSString* toNSString(Json::Value value){ 
  190. return toNSString(value.asString()); 
  191. static String Create(Json::Value value){ 
  192. String str(toNSString(value)); 
  193. return str; 
  194. }; 

从源码中可以 看出,为了支持正则式,这里使用了RegexKitLite库,网上有不少网友问为什么使用这个H文件时,如果.m文件改成支持C++的.mm后缀之后, 会造编译错误('capture Count'was not declared in this scope),导致程序运行不起来。而网友的解决方法就是不使用.MM后缀文件。但经过分析我发现是BLOCK块语法导致编译错误的,在经过不断尝试之 后,发现只要修改该头文件中的如下宏定义,就可以将该头文件包含在MM文件中了:

#if !defined(RKL_BLOCKS) && defined(NS_BLOCKS_AVAILABLE) && (NS_BLOCKS_AVAILABLE == 1)

#define RKL_BLOCKS 1   //此处需要从1改为0

#endif

另外上面的String类的实现中,方法名称主要是参考C#中的字符串处理类的名称。所以可以很方法的使用。

NSString *test1 = @"imgOnLoad";

NSString *test2 = @"  trim test  ";

String s(test1);

test1 = s.trim().toUpper();

比如下面将字符串转小写并TRIM掉首尾空格:

NSString *test1 = @"imgOnLoad";

NSString *test2 = @"  trim test  ";

String s(test1);

test1 = s.trim().toUpper();

判断字符串是否以指定内容开始或结束时:

BOOL result = s.startWith(@"imga");

result = s.endWith(@"load");

也可以直接将NSString*赋值给String实例

s = test2;

获取字符串长度

int i = s.length();

字符串格式化及绑定:

String s1(123);

s1 = String::format(@"%@daizhj%@", @"diaoyudao", @"123");

String ss = String::format(@"http://%@www.sina.com.cn%@/ http", @"1", @"hello");

字符串替换:

test2 = s.replace(@"http", @"ddz").replace(@"sina", @"163").toString();

以及在C#开发中学中的StringBuilder类的appendFormat方法,这里也有相关方法对应:

test2 = s.appendFormat(@"%@daizhj%@", @"diaoyudao", @"123")

.appendFormat(@"%@fffffff%@", @"dddddd", @"123")

.appendFormat(@"%@aaaa%@", @"vvvvvv", @"123").toString();

截取子串:

test2 = s.subString(2, 10);

test2 = s.subString(10);

查找字符是否存在:

BOOL search = s.contains(@"dadddd");

除此以外,还有正则替换查找,url地址的编解码,以及String对象转换成其它不同类型如date, int, float等。

责任编辑:闫佳明 来源: oschina
相关推荐

2013-05-02 13:06:05

C++遇到iOS应用开SQLITE

2010-02-01 16:46:07

C++格式化字符串

2010-02-02 11:27:16

C++字符串

2021-09-07 09:23:07

C++字符串算法

2017-12-07 16:08:47

数据优化HTML字符串

2010-11-26 09:51:54

MySQL字符串

2021-07-30 06:22:37

C++字符型字符串

2010-02-04 17:39:48

C++字符串类型

2010-02-04 17:32:43

C++中C风格字符串

2014-04-14 10:21:15

开发运维DevOps

2009-09-02 15:53:27

C#判断字符串应用

2016-12-30 13:32:24

字符串算法代码

2023-12-11 15:18:03

C++字符串Unicode

2010-02-02 18:01:47

C++字符串替换函数

2009-09-01 17:50:23

C#截取字符串

2021-08-20 06:58:31

C++Python函数

2010-02-04 10:52:36

C++字符串分割函数

2024-03-11 06:05:00

C++字符串

2024-02-22 09:46:04

C++字符串格式化开发

2016-12-30 13:16:51

字符串算法代码
点赞
收藏

51CTO技术栈公众号