iOS之字符串拷贝

1,324 阅读3分钟

这是我参与11月更文挑战的第29天,活动详情查看:2021最后一次更文挑战

完成字符串拷贝可以使用sprintf、strcpy、以及memcpy函数,这些函数的区别在于实现功能以及操作对象不同。

  • strcpy:函数操作的对象是字符串,完成从源字符串到目的字符串的拷贝功能。
  • sprintf:这个函数主要用来实现(字符串或基本数据类型)向字符串的转换功能。如果源对象是字符串,并且制定%s格式符,也可以实现字符串拷贝功能。
  • memcpy:函数顾名思义就是内存拷贝,实现将一个内存快的内容复制到另一个内存块这一功能。内存块由其首地址以及内存长度信息、并且对象具有可操作性即可。鉴于memcpy函数等长拷贝的特点以及数据类型代表的物理意义,memcpy函数通常限于同种类型数据或者对象之间的拷贝,其中当然也包括字符串拷贝以及基本数据类型的拷贝。

对于字符串拷贝来说,用上述三个函数都可以实现,但是其实现的效率和使用的方便程度不同:

  • strcpy 无疑是最合适的选择:效率高且调用方便。
  • sprintf 要额外指定格式符并且进行格式转化,麻烦且效率不高。
  • memcpy 虽然高效,但是需要额外提供拷贝的内存长度这一参数,易错且使用不便;并且如果长度指定过大的话(最优长度是源字符串长度+1),还会带来性能的下降。其实strcpy函数一般是在内部调用memcpy函数或者用汇编直接实现的,以达到高效的目的。因此,使用memcpystrcpy 拷贝字符串在性能上应该没有什么大的差别。
  • 对于非字符串类型的数据的复制来说,strcpysprintf一般就无能为力了,可是对memcpy却没什么影响。但是,对于基本数据类型来说,尽管可以用memcpy进行拷贝,由于有赋值运算符可以方便且高效地进行同种或兼容类型的数据之间的拷贝,所以这种情况下memcpy几乎不被使用。memcpy的长处是用来实现(通常是内部实现居多)对结构或者数组的拷贝,其目的是活着高效,活着使用方便,甚或两者兼有。

sprintf,strcpy,memcpy使用上的注意事项

  • strcpy是一个字符串拷贝的函数,它的函数原型为strcpy(char dst, const char src);
  • src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为‘\0’,由于拷贝的长度不是由我们自己控制的,所以这个字符串拷贝很容易出错。
  • 具备字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型为memcpy(char dst, const char src, unsigned int len);将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。但是会有内存读写错误。(比如len的长度大于要拷贝的空间或目的空间)
  • sprintf是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,造成溢出。