您的位置:首页 > 其它

几个常见字符串处理函数的实现原理

2014-07-09 18:26 495 查看
字符串是一种常见的数据结构,对字符串的处理又可以十分灵活,所以在实际开发,尤其是非数值处理中,字符串的应用非常广泛。虽然很多字符串操作都封装在了函数库里,应用程序可以直接通过调用库函数来实现字符串处理,然而对于开发者而言,若能了解其底层实现原理,对于应用编程而言还是大有裨益的。
这篇文章主要介绍几种常用的字符串处理函数的实现原理。

一、strlen函数

strlen函数:计算字符串的实际长度,不包括’\0’。

算法:从第一个字符开始扫描,直到遇见第一个’\0’,停止扫描,返回字符串长度。

代码如下:

int strlen(const char *str)
{
int n=0;
assert(str!=NULL);
while(*str++!='\0')
++n;
return n;
}




二、strcat函数

strcat函数:将源字符串str2添加到目的字符串str1的末尾,同时覆盖str1末尾的’\0’,并在新的str1末尾添加’\0’,返回指向str1的指针。

算法:扫描str1,直到遇见’\0’,将str2逐个字符添加到str1末尾,最后添加’\0’。

代码如下:

char *strcat(char *str1, const char *str2)
{
char *p=str1;
assert( (str1!=NULL) && (str2!=NULL) );
while(*str1!='\0')
str1++;
while(*str1++=*str2++);
return p;
}


三、strcmp函数

strcmp函数:比较str1和str2两个字符串的大小,若str1>str2,则返回正数;若str1<str2,则返回负数;若str1==str2,则返回0。

算法:逐个比较str1和str2的每个字符,若相等且未遇见’\0’,则继续比较下一个字符,否则,返回*str1和*str2的差值。

代码如下:

int strcmp(const char *str1, const char *str2)
{
assert( (str1!=NULL) && (str2!=NULL) );
while(*str1 && *str2&& (*str1==*str2))
{
str1++;
str2++;
}
return *str1 - *str2;
}


四、strcpy函数

strcpy函数:将字符串str2(包括NULL)复制到字符串str1,返回指向str1的指针。

算法:将str2中逐个字符添加到str1指向的地址空间,必须保证str1指向的地址空间足够大。

代码如下:

char *strcpy(char *str1, const char *str2)
{
char *p=str1;
assert( (str1!=NULL) && (str2!=NULL) );
while(*str1++=*str2++);
return p;
}


五、atoi函数

atoi函数:把字符串转换成整数。

算法:首先跳过空格或制表符,再判断符号,最后通过减去’0’转化整数,跳过非数值,返回转换后的整数。

代码如下:

int atoi(char *str)
{
int sum=0,sign=1;
char *p=str;
assert(str!=NULL);
if(' '==*p||'\t'==*p)
p++;
if('-'==*p)
sign=-1;
if('-'==*p||'+'==*p)
p++;
while(*p>='0' && *p<='9')
{
sum = sum*10 + *p-'0';
p++;
}
return sign*sum;
}

六、itoa函数

itoa函数:将整数转化为字符串。

算法:先判断整数的符号,若为负,则将其转换为正;将整数从个位到最高位依次存放在临时数组tmp中,如果是负整数,则再添加一个负号;逆序将临时数组的各个元素放在str字符数组中,在最后添加一个空字符。

代码如下:

void itoa(int num, char str[])
{
int i=0,j=0,sign=num;
char tmp[10];
if(num<0)
num=-num;
do
{
tmp[i++]=num%10 + '0';
num/=10;
}while(num>0);
if(sign<0)
tmp[i++]='-';
tmp[i]='\0';
i--;
while(i>=0)
{
str[j]=tmp[i];
j++;
i--;
}
str[j]='\0';
}


七、strstr函数
strstr函数:搜索一个字符串在另一个字符串中的第一次出现。找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址;如果未找到所搜索的字符串,则返回NULL。
char *StrStr(const char *string, const char *substring)		//调用库函数实现
{
int len1 = strlen(string);
int len2 = strlen(substring);

assert(string != NULL && substring != NULL);

if (len2 > len1)
return NULL;		//子串比母串长,返回NULL
while (*string != '\0')
{
if ( (*string == *substring) && (strncmp(string, substring, len2) == 0) )	//(*string == *substring)不成立,则(strncmp(string, substring, len2) == 0)不执行
return (char *)string;		//string由const char*转换为char*

string++;	//不可写在while的循环条件里
}

return NULL;
}

char *StrStr(const char *string, const char *substring)		//不调用库函数实现
{
int i, j, tmp;

assert(string != NULL && substring != NULL);

for (i = 0; string[i] != '\0'; i++)
{
tmp = i;	//tmp保留主串中的起始判断下标位置
j = 0;
while (string[i++] == substring[j++])
{
if (substring[j] == '\0')
return (char *)&string[tmp];
}
i = tmp;	//将i重新改为tmp
}

return NULL;
}


Wednesday,July 09, 2014
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
补:
strncpy、strncmp、strncat、memcpy、memset
char *Strncpy(char *dest, const char *src, unsigned int n)
{
assert(dest != NULL && src != NULL);

char *tmpdest = dest;

while(n-- > 0 && *src != '\0')
*tmpdest++ == *src++;
*tmpdest = '\0';

return dest;
}
int Strncmp(const char *s, const char *t, unsigned int n)
{
assert(s != NULL && t != NULL);

while( *s && *t && (*s == *t) && (n-- > 0) )
{
s++;
t++;
}

return (*s - *t);
}
char *Strncat(char *dest, const char *src, unsigned int n)
{
assert(dest != NULL && src != NULL);

char *tmpdest = dest;
while(*tmpdest != '\0')
tmpdest++;
while(*src && (n-- > 0))
*tmpdest++ = *src++;

*tmpdest = '\0';

return dest;
}
void *Memcpy(void *dest, const void *src, size_t count)
{
assert(dest != NULL && src != NULL);

char *tmpdest = (char *)dest;
char *tmpsrc = (char *)src;

while (count-- > 0)
*tmpdest++ = *tmpsrc++;

return dest;
}
void *Memset(void *buffer, int c, size_t count)
{
assert(buffer != NULL);

char *tmpbuffer = (char *)buffer;
while(count--)
{
*tmpbuffer++ = (char)c;
}

return buffer;
}


2014.9.25
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: