字符串操作是编程中最常见的一种,但就是这看似简单的操作,曾经使无数的IT英雄前赴后继地跌倒。
字符串操作不规范,可能导致隐形问题或显形错误。这类隐形问题或显形错误,有些时候仅仅通过测试,是不能检查不出来的,因为部分数据区内容的错位并不足以影响到系统的运行。但运行到特定时机下,系统会表演出异常给你看,到时候,你就只有傻眼的尴尬。
字符串操作导致系统崩溃、运行异常等险情,屡见不鲜。出现这种情况后,你可能进行了大量测试或阅读了N遍代码,却对字符串的不合法使用熟视无睹,花费了你的时间,消磨你的斗志,好在最后,你一拍大腿,“这儿有问题吧?”,噩梦终于结束。
字符串函数族中,strcpy、strcat是导致字符串缓冲区混乱的罪魁祸首,而合理使用memcpy、strncpy,能保证系统的安全性。
一、字符串变量定义,建议采用如下方式:
char fname[FILE_NAME_LEN+1];
其中FILE_NAME_LEN为字符串缓冲区的有效数据长度,多出的1个字节用来存储'/0',各归其位,方能和平共处。
二、初始化的方法:
1> char fname[FILE_NAME_LEN+1] = {0};
2> memset(fname, 0, sizeof(fname));
推荐第一种,效率最高。当然,在使用过程中的初始化,使用第二种即可。
数组的长度表示,最好用sizeof,是一个完全之策,不会因数组的深度发生变化而要修改代码。
三、使用方法:
char strDest[FILE_NAME_LEN+1] = {0};
strncpy(strDest, str2, FILE_NAME_LEN);
strDest[FILE_NAME_LEN] = '/0';
此时,strDest中可能包含部分垃圾数据,但垃圾数据的前面,必定存在一个'/0';或者strDest中的数据都是有效的,由最后的'/0'来保证strDest缓冲区的安全。
之所以推荐少用strcpy、strcat函数,是因为strcpy、strcat函数没有为你考虑src的缓冲区的大小,仅仅是考虑了dest缓冲区数据的连续性。如果dest数据区是有问题的或有效长度大于src,你可就栽到在这strcpy上了。
char *strcpy(char * dest, const char * src)
{
assert(dest != NULL && src != NULL);
char * cp = dest;
while( *cp++ = *src++ ) ;
return( dest );
}
char *strncpy(char *dest, const char *source, size_t count)
{
char *start = dest;
while(count && (*dest++ = *source++))
count--;
if(count)
while(--count)
*dest++ = '/0';
return(start);
}
当然,也不是说strcpy、strcat函数不能用,除非你确认dest指向的有效数据区,比src的数据区要短,也就是说你必须明确地知道,'/0'在什么位置,是在字符串之内,还是字符串之外。否则的话,你最好不要使用strcpy,运行中的事情,谁又能够说得清呢!
其他编程语言,与此类似。