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中
方法一:
方法二:可以直接调用ctype库中的函数实现
为了防止内存重叠,可以做如下修改:
注意:函数调用时,返回值只是地址。
memcpy和strcpy区别:
1.strcpy只能复制字符串,而memcpy不限制数据类型
2.strcpy不需要知道字符串长度,一直复制,直到'\0',这样容易溢出,而memcpy遇到'\0'不停止,指导n才结束。
对于memset来说,没有越界不越界之分,数组的界是程序员逻辑一部分,memset不管,因此如果在超出数组上限时,超出内存都没有被其他进程所占用,那么一切正常。但是如果有至少一个字节的内存区域属于其他进程,那么我这个程序将会出现运行时错误。
其中: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不管,因此如果在超出数组上限时,超出内存都没有被其他进程所占用,那么一切正常。但是如果有至少一个字节的内存区域属于其他进程,那么我这个程序将会出现运行时错误。
相关文章推荐
- memcpy, strcpy, strlen, strcmp, itoa, atoi 的函数实现
- strlen,strcpy,strcat,strcmp四个函数的原型,memcpy,memset的实现
- memcmp,memcpy,memmove,memset,strcat,strcmp,strcpy,strlen 8个函数的实现
- strcpy()、memcpy()、memmove()、memset() 、strcmp()、strlen()、strcat()的实现
- 部分字符串库函数的重写(源码) toupper,memcpy,memmove,memset,memchr,strlen,strcpy,strcat,strcmp,strchr
- 基础函数的实现(strcpy,strcat, strcmp, atoi, itoa)
- atoi、itoa,strcpy,strcmp,memcpy等实现
- 纯C 字符串操作函数 实现 (strcpy, strncpy, memcpy, memset, strcat, strlen ... )
- atoi、itoa,strcpy,strcmp,memcpy等实现
- 部分字符串库函数的重写(源码) toupper,memcpy,memmove,memset,memchr,strlen,strcpy,strcat,strcmp,strchr
- 纯C 字符串操作函数 实现 (strcpy, strncpy, memcpy, memset, strcat, strlen ... )
- strcpy,strcmp,strcat,memcpy,memmov,memset,memcmp的实现
- 工作的准备:atoi,itoa,strcpy,memcpy,strcmp,二分查找,strcat
- 纯C 字符串操作函数 实现 (strcpy, strncpy, memcpy, memset, strcat, strlen ... )
- 模拟实现: strstr strcpy strlen strcat strcmp memcpy memmove
- 模拟实现strstr,strcpy,strlen,strcat,strcmp,memcpy,memmove
- 模拟实现strlen,strcpy,strcat,strstr,strcmp,memcpy,memmove
- strcpy strlen memcpy strcat strcmp strstr strrev函数的实现代码
- strcpy,strcmp,strstr,strcat,memcpy,memmove,memset的模拟实现
- strlen, strcpy, strcat, strcmp, memset... (字符串操作函数的实现)