您的位置:首页 > 其它

atoi itoa strcpy strcmp strlen strcat memcpy memset实现

2014-03-21 16:17 567 查看
实现总结一下C常用库中的一些函数,把书上的变成自己的!

其中:atoi 在标准库,但itoa不在标准库中, stdlib中,strcpy,strcmp,strlen,strcat,memcpy,memset 在库string中

一 atoi

原型为 int atoi(const char *nptr),实现字符串转为整型。
方法一:
int myatoi(const char *nptr)
{
assert(nptr != NULL);

int i = 0;
int sign = 1;
int number = 0;

while(' ' == nptr[i] || '\t'== nptr[i])
i++;
sign = (nptr[i] == '-') ? -1 : 1;

while('-' == nptr[i] || '+' == nptr[i])
i++;
while(nptr[i] != '\0')
{
number = number*10 + (nptr[i] - '0');
i++;
}
number = sign * number;
return number;

}
这种方法是网上常见的方法,但是在测试的过程中发现,当输入字符串为“ -123 ”时,输出结果不是-123,那时因为在最后一次循环中,只判断了是否为结束符,而没有判断是否不是数字,所以我做了如下修改:
while(nptr[i] >= '0' && nptr[i] <='9' )
{
number = number*10 + (nptr[i] - '0');
i++;
}
其效果等效于方法二中的 isdigit()函数。
方法二:可以直接调用ctype库中的函数实现
int myatoi(const char *nptr)
{
assert(nptr != NULL);

int i = 0;
int sign = 1;
int number = 0;

while(isspace(nptr[i]))
i++;
sign = (nptr[i] == '-') ? -1 : 1;

while('-' == nptr[i] || '+' == nptr[i])
i++;
while(isdigit(nptr[i]))
{
number = number*10 + (nptr[i] - '0');
i++;
}
number = sign * number;
return number;
}


二 itoa

原型为 void itoa(int n, char [ ]),实现把整型转为字符串。

由于整数长度未知,不能直接获得整数,需要对其进行逆序。

void myitoa(const int num,char *s)
{
int n = num;
int i = 0;
int j = 0;

char *temp = new char[10];
if(n < 0)
{
s[i] = '-';
i++;
n = -num;
}

while(n > 0)
{
temp[j] = n%10 + '0';
n = n/10;
j++;
}
temp[j] = '\0';
j--;

while(j >=0)
s[i++] = temp[j--];
s[i] = '\0';
}

三 strcpy

原型为 char* strcpy(char *str1,const char * str2),把str2所指的字符串复制到str1中,返回目的存储区的初始地址

char* myStrcpy(char* dst,const char* src)
{
assert( src != NULL);
assert( dst != NULL);
char *address = dst;
//	memcpy(dst,src,strlen(src)+1);
while((*dst++ = *src++) != '\0');

return address;
}


四 strcmp

原型为 int strcmp(const char *str1,const char * str2),比较str1,str2所指字符串的大小,如果str1 = str2,返回0,str1 < str2,返回<0,str1 > str2 ,返回 >0。

int mystrcmp(const char *dst,const char *src)
{
assert(dst != NULL && src != NULL);

while(*dst && *src && *dst == *src)
{
dst++;
src++;
}
return *dst-*src;
}

五 strlen

原型为 int strlen(const char *str),返回str的字符长度,不包括'\0'(字符串中的空格包括在内)
int mystrlen(const char *src)
{
assert(src != NULL);
int length = 0;
while(*src != '\0')
{
length++;
src++;
}
return length;
}

六 strcat

原型为 char *strcat(char *str1,const char *str2),把str2所指的字符串连接到str1,并返回目的存储区初始地址
char *mystrcat(char *dst,const char *src)
{
assert(dst != NULL && src != NULL);

char *address = dst;
while(*dst != '\0')
dst++;
while((*dst ++ = *src ++) != '\0');
*dst = '\0';
return address;
}
注意:在dst指针移到dst末尾时,不能
while(*dst++ != '\0');
如果这样的话,不能达到连接的效果,最后返回的只是dst的内容。这是因为* 和 ++ 的优先级一样,则自左向右执行,即当判断dst为结束符,其会指向下一个字节,即'\0'的下一个字节。所以address保存的内容是:dst ‘\0’ src '\0',输出时遇'\0'停止,即dst '\0'。

七 memcpy

原型为 void *memcpy(void *str,const void *str2,size_t n),存储器拷贝,把str指的n个字符拷贝到str1中,返回目的存储区起始地址
void *mymemcpy(void *dst,const void *src,size_t n)
{
assert(dst != NULL && src != NULL);
//assert((dst >= src+n) || (src >dst+n));

char *tempdst =(char *) dst;
char *tempsrc = (char *)src;

while(n-- )
*tempdst++ = *tempsrc++;

return dst;
}


为了防止内存重叠,可以做如下修改:
void *mymemcpy(void *dst,const void *src,size_t n)
{
assert(dst != NULL && src != NULL);
char *tempdst =(char *) dst;
char *tempsrc = (char *)src;
//assert((tempdst >= tempsrc+n) || (tempsrc > tempdst+n));

size_t i = 0;
if(tempdst > tempsrc && tempdst < tempsrc + n)
{

while(n--)
*tempdst++ = *tempsrc++;

}
else
{

while(n--)
*tempdst++ = *tempsrc++;

}

return dst;
}

int _tmain(int argc, _TCHAR* argv[])
{
char src[] = "abadc";
char dst[] = "SCH";
mymemcpy(dst,src,2*sizeof(char));
cout <<dst<<endl;
return 0;
}

注意:函数调用时,返回值只是地址。

memcpy和strcpy区别:
1.strcpy只能复制字符串,而memcpy不限制数据类型
2.strcpy不需要知道字符串长度,一直复制,直到'\0',这样容易溢出,而memcpy遇到'\0'不停止,指导n才结束。

八 memset

原型为 void *memset(void *str,int v,size_t n),把str所指区域的前n个字节均设为v,返回的是该区域的起始地址。
void *mymemset(void *dst,int v,size_t n)
{
assert(dst != NULL);
char *address = (char *)dst;
while(n--)
*address++ = v;
return dst;
}


对于memset来说,没有越界不越界之分,数组的界是程序员逻辑一部分,memset不管,因此如果在超出数组上限时,超出内存都没有被其他进程所占用,那么一切正常。但是如果有至少一个字节的内存区域属于其他进程,那么我这个程序将会出现运行时错误。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐