自己编写strlen、strcpy和strcmp源码
1、不使用库函数实现strcpy
#include
char*strcpy(char*dst,const char*src)
{
assert((dst !=NULL)&&(src !=NULL));
char*tmp = dst;
while((*dst++=*src++)!='\0'){
/* nothing */;
}
return tmp;
}
需要注意几个方面的问题:
1、注意编程风格。比如,使用dst、src这样增强可读性的名字。
2、使用断言assert来检验输入参数的有效性。
assert宏的原型定义在
3、使用const来约束src,表明src对应的内容不能被修改。
4、返回dst,以便实现链式表达式这样的机制。
2、strlen函数源码
size_t strlen_b(const char *str)
{
const char *cp = str;
while (*cp++)
;
return (cp - str - 1);
}
3、微软strcmp函数源码
int __cdecl strcmp (const char *src, const char *dst)
{
int ret = 0 ;
while(!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
{
++src;
++dst;
}
if ( ret < 0 )
ret = -1 ;
else if ( ret > 0 )
ret = 1 ;
return( ret );
}
4、面试中strcpy源码的判分标准
如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:2分
void strcpy( char *strDest, char *strSrc )
{
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
4分
void strcpy( char *strDest, const char *strSrc )
//将源字符串加const,表明其为输入参数,加2分
{
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
7分
void strcpy(char *strDest, const char *strSrc)
{
//对源地址和目的地址加非0断言,加3分
assert( (strDest != NULL) &&(strSrc != NULL) );
while( (*strDest++ = * strSrc++) != ‘\0’ );
}
10分
//为了实现链式操作,将目的地址返回,加3分!
char * strcpy( char *strDest, const char *strSrc )
{
assert( (strDest != NULL) &&(strSrc != NULL) );
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ );
return address;
}
从2分到10分的几个答案我们可以清楚的看到,需要多么扎实的基本功才能写一个完美的strcpy。
5、对strlen的掌握,它没有包括字符串末尾的'\0'
看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:
int strlen( const char *str ) //输入参数const,2分
{
assert( strt != NULL ); //断言字符串地址非0,3分
int len;
while( (*str++) != '\0' ) // 3分
{
len++;
}
return len;
}
C字符串处理函数全
strcpy(char destination[], const char source[]); strcpy:将字符串source拷贝到字符串destination中。 strcpy函数应用举例 原型:strcpy(char destination[], const char source[]); 功能:将字符串source拷贝到字符串destination中 例程: #include 一、s trlen函数 strlen()函数用来计算字符串的长度,其原型为: unsigned int strlen (char *s); 【参数说明】s为指定的字符串。 strlen()用来计算指定的字符串s 的长度,不包括结束字符"\0"。 【返回值】返回字符串s 的字符数。 注意一下字符数组,例如 char str[100] = "https://www.360docs.net/doc/069181849.html,/cpp/u/biaozhunku/"; 定义了一个大小为100的字符数组,但是仅有开始的11个字符被初始化了,剩下的都是0,所以 sizeof(str) 等于100,strlen(str) 等于11。 如果字符的个数等于字符数组的大小,那么strlen()的返回值就无法确定了,例如 char str[6] = "abcxyz"; strlen(str)的返回值将是不确定的。因为str的结尾不是0,strlen()会继续向后检索,直到遇到'\0',而这些区域的内容是不确定的。 注意:strlen() 函数计算的是字符串的实际长度,遇到第一个'\0'结束。 如果你只定义没有给它赋初值,这个结果是不定的,它会从首地址一直找下去,直到遇到'\0'停止。而sizeof返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符,strlen()是函数。 二、s trcat函数 strcat() 函数用来连接字符串,其原型为: char *strcat(char *dest, const char *src); 【参数】dest 为目的字符串指针,src 为源字符串指针。 strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个NULL。 注意:dest 与 src 所指的内存空间不能重叠,且 dest 要有足够的空间来容纳要复制的字符串。 编写strcpy函数和类String的构造函数、析构函数、赋值函数和重载运算符函数 已知strcpy函数的原型是 char *strcpy(char *strDest, const char *strSrc); 其中strDest是目的字符串,strSrc是源字符串。 (1)不调用C++/C的字符串库函数,请编写函数strcpy char *strcpy(char *strDest, const char *strSrc); //将源字符串加const,表明其为输入参数 { assert((strDest!=NULL) && (strSrc !=NULL)); // 2分 //对源地址和目的地址加非0断言 char *address = strDest; // 2分//为了实现链式操作,将目的地址返回 while( (*strDest++ = * strSrc++) != …\0? ) // 2分 NULL ; return address ; // 2分 } (2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值? 答:为了实现链式表达式。// 2分 例如int length = strlen( strcpy( strDest, “hello world”) ); 二、网上广泛流传的,也是摘自林锐的 http://www.blog.sh/user3/skyflowing/archives/2006/60452.html 题目: 已知strcpy函数的原型是: char * strcpy(char * strDest,const char * strSrc); 1.不调用库函数,实现strcpy函数。 2.解释为什么要返回char *。 示例 1.字符串输出示例。 程序: #include int x,y; x=strlen(a); y=strlen("abc13"); printf("%d\n%d\n\n",x,y); } 结果: 4.字符串连接函数的使用。 程序: #include 题目: 已知strcpy函数的原型是: char * strcpy(char * strDest,const char * strSrc); 1.不调用库函数,实现strcpy函数。 2.解释为什么要返回char *。 (一)高质量c++编程上的答案 五、编写strcpy函数(10分) 已知strcpy函数的原型是 char *strcpy(char *strDest, const char *strSrc); 其中strDest是目的字符串,strSrc是源字符串。 (1)不调用C++/C的字符串库函数,请编写函数 strcpy char *strcpy(char *strDest, const char *strSrc) { assert((strDest!=NULL) && (strSrc !=NULL)); // 2分 char *address = strDest; // 2分 while( (*strDest++ = * strSrc++) != '\0' ) // 2分 NULL ; return address ; // 2分 } ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。如果ASSERT()中的条件不成立(比如 ASSERT(0) ; ),会弹出一个比较吓人的对话框。点击重试,可以到达 ASSERT 断言不成立的那一行. C++常用库函数atoi,itoa,strcpy.strcmp的实现 1.//整数转换成字符串itoa函数的实现 #include "stdafx.h" 1.//整数转换成字符串itoa函数的实现 #include "stdafx.h" #include temp[i++] = '-';//对于负数,要加以负号 } temp[i] = '\0'; i--; while(i>=0)//反向操作 { str[j] = temp[i]; j++; i--; } str[j] = '\0'; } 2. //字符串转换成整数atoi函数的实现 int atoiTest(char s[]) { int i = 0,sum = 0,sign; //输入的数前面可能还有空格或制表符应加判断 while(' '==s[i]||'\t'==s[i]) { i++; } sign = ('-'==s[i])?-1:1; if('-'==s[i]||'+'==s[i]) { i++; } while(s[i]!='\0') { sum = s[i]-'0'+sum*10; i++; } return sign*sum; } 3.//字符串拷贝函数 #include "stdafx.h" #include strcpy函数的用法 strcpy(s1,s2);strcpy函数的意思是:把字符串s2中的内容copy到s1中,连字符串结束标志也一起copy. 这样s1在内存中的存放为:ch\0; 在cout< ***************数学相关**************** 1、函数名称: abs 函数原型: int abs(int x); 函数功能: 求整数x的绝对值 函数返回: 计算结果 参数说明: 所属文件: <>,<> 使用范例: #include <> #include <> int main() { int number=-1234; printf("number: %d absolute value: %d",number,abs(number)); return 0; } 2、函数名称: fabs 函数原型: double fabs(double x); 函数功能: 求x的绝对值. 函数返回: 计算结果 参数说明: 所属文件: <> 使用范例: #include <> #include <> int main() { float number=; printf("number: %f absolute value: %f",number,fabs(number)); return 0; } 3、函数名称: sqrt 函数原型: double sqrt(double x); 函数功能: 计算x的开平方. 函数返回: 计算结果 参数说明: x>=0 所属文件: <> 使用范例: #include <> #include <> int main() { double x=,result; result=sqrt(x); printf("The square root of %lf is %lf",x,result); return 0; } 4、函数名称: pow 函数原型: double pow(double x,double y); 函数功能: 计算以x为底数的y次幂,即计算x^y的值. 函数返回: 计算结果 Strcpy函数 原型声明:extern char *strcpy(char dest[],const char *src); 头文件:#include 字符串处理函数大全 bcmp(比较内存内容)相关函数 bcmp,strcasecmp,strcmp,strcoll,strncmp,strncasecmp 表头文件;include strcpy ,strncpy ,strlcpy地用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界。 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式。 1. strcpy 我们知道,strcpy 是依据/0 作为结束判断的,如果to 的空间不够,则会引起buffer overflow。strcpy 常规的实现代码如下(来自OpenBSD 3.9): char * strcpy(char *to, const char *from) { char *save = to; for (; (*to = *from) != '/0'; ++from, ++to); return(save); } 但通常,我们的from 都来源于用户的输入,很可能是非常大的一个字符串,因此strcpy 不够安全。 2. strncpy 在ANSI C 中,strcpy 的安全版本是strncpy。 char *strncpy(char *s1, const char *s2, size_t n); 但strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定n 并不是sizeof(s1),而是要复制的char 的个数。一个最常见的问题,就是strncpy 并不帮你保证/0 结束。 char buf[8]; strncpy( buf, "abcdefgh", 8 ); 看这个程序,buf 将会被"abcdefgh" 填满,但却没有/0 结束符了。 另外,如果s2 的内容比较少,而n 又比较大的话,strncpy 将会把之间的空间都用/0 填充。这又出现了一个效率上的问题,如下: char buf[80]; strncpy( buf, "abcdefgh", 79 ); 上面的strncpy 会填写79 个char,而不仅仅是"abcdefgh" 本身。 strncpy 的标准用法为:(手工写上/0) strcpy用法 写法: char *strcpy(char* dest, const char* src) { assert(NULL != dest); assert(NULL != src); char *tmp = dest; //因为*tmp不是布尔值所以有必要比较 while('\0' != (*tmp++=*src++)); return(dest); } MS中的定义: (%VC%/vc7/crt/src/intel/strcat.asm) page ;*** ;char *strcpy(dst, src) - copy one string over another ; ;Purpose: ; Copies the string src into the spot specified by ; dest; assumes enough room. ; ; Algorithm: ; char * strcpy (char * dst, char * src) ; { ; char * cp = dst; ; ; while( *cp++ = *src++ ) ; ; /* Copy src over dst */ ; return( dst ); ; } ; ;Entry: ; char * dst - string over which "src" is to be copied ; const char * src - string to be copied over "dst" ; ;Exit: ; The address of "dst" in EAX ; ;Uses: ; EAX, ECX ; ;Exceptions: ;************************************************************* 1.没有检查输入的两个指针是否有效。 2.没有检查两个字符串是否以NULL结尾。 3.没有检查目标指针的空间是否大于等于原字符串的空间。 https://www.360docs.net/doc/069181849.html,/htm/netp8/17002.html /* the emplementation in VC++ */ char* strcpy(char* dest, const char* src) { char* tmp = dest; while (*tmp++ = *src++) ; return dest; } /* the emplementation in Linux */ char* strcpy(char* dest, const char* src) { char* tmp = dest; while ((*tmp++ = *src++) != '\0') ; 字符函数和字符串函数 头文件:字符串函数头文件:#include 5. Scanf(“%d%c%f”,&a,&b,&c); 输入时1234a123h26↙在输入遇到时空格回车 tab或其他非法输入就会认定输入完毕 Gets (字符数组):读入字符串函数 Gets(str)从键盘键入a b↙括号里为字符数组str的起始地址,Puts(字符数组):输出字符串函数 Strcat(字符数组1,字符数组2):字符串连接函数(2连接在1后面) Strcpy和strncpy:字符串复制函数 Strcpy(字符数组1,字符数组2):将2复制到1 数组1 要为数组名,字符串2可以为数组名或者字符串 Strncpy(str1,str2,2):将str2的前两个字符复制到str1,取代str1的前两个字符 Strcmp:字符串比较函数 Strcmp(str1,str2):相等则为0(对字符串自左向右逐个字母进行比较) Strlen(字符数组):测字符串的实际长度 Strlwr(字符串)将字符串转换为大写 Strupr(字符串)将字符串转换为小写 使用strcmp()函数时常出现的问题 原型:int strcmp(char *str1,char *str2) 功能:把两字符串str1与str2进行比较,当str1>str2,函数返回1,当str1==str2时,函数返回0,当str1 #include 常用字符串函数 /************************************* ************************************* ***** 一.NSString ************************************* ************************************* *****/ /*----------------创建字符串的方法 ----------------*/ //1、创建常量字符串。NSString *astring = @"Welcome to 1000phone"; //2、通过实例化方法initWithString:实例化一个字符串对象 NSString *astring = [[NSString alloc] initWithString:@" I love iOS!"]; NSLog(@"astring:%@",astring);?[astring release]; //3、用标准c创建字符串: initWithCString:encoding:方法 const char *cString = "I love iphone"; NSString * aString = [[NSString alloc]initWithCString:cString encoding:NSUTF8StringEncoding];? NSLog(@"astring:%@",aString);?[aString release]; 或者:用initWithUTF8String:实例化一个字符串对象const char *p = " Welcome to Beijing!";?NSString *string = [[NSString alloc]initWithUTF8String:p]; //4、创建格式化字符串:占位符(由一个%加一个字符组成) int age = 23;?NSString *astring = [[NSString alloc] initWithFormat:@”I am %d”,age]]; NSLog(@"astring:%@",astring);?[astring release]; //5、通过静态方法创建字符串对象NSString * str1 = [NSString stringWithString:@"I love programming!"];?NSString * str2 = [NSString stringWithUTF8String:" I love programming!"]; NSString * str3 = [NSString 用C语言实现strcpy,strncpy,strcat,strcmp,strlen函数(本文介绍的函数都是在Linux平台下实现的) 首先介绍下文件存放结构: 1.所有文件都在Mystring这个文件夹里: 2.Mystring文件夹里又有四个文件夹(bin, include, o_file, src)和一个主makefile(Makefile)文件: 3.bin文件夹里存放的是编译生成的执行文件: 4.include文件夹里存放的是头文件: 5.o_file文件夹里存放的是编译生成的.o文件: 6.src文件夹里存放的是各个源文件(主函数,及几个要实现的string处理函数): 下面开始看代码: 头文件,Mystring.h: (简单,就不注释了) #ifndef __MYSTRING_H__ #define __MYSTRING_H__ #include int mystrlen(const char *strSrc); char *mystrncpy(char *strDest, const char *strSrc, int n); char *mystrmemcpy(char *strDest, const char *strSrc, int n); #endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// strcpy函数,mystrcpy.c: #include"../include/mystring.h" char *mystrcpy(char *strDest, const char *strSrc) { assert(NULL != strDest && NULL != strSrc); char *str = strDest; Strcat,strcpy,strcmp,Strlen函数原型 1、Strcat函数原型如下: #include p_s = s; p_t = t; for(i = 0; i < strlen(s); i++) *(p_st++) = *(p_s++); for(i = strlen(s); i<(strlen(s) + strlen(t)); i++) *(p_st++) = *(p_t++); *p_st = '\0'; return st; } int main() { char *dst = {"wo ai "}; char *src = {"wo de guo jia !"}; printf("%s\n",strca(dst,src)); return 0; } 2、Strcpy函数原型如下: char *strcpy(char *strDest, const char *strScr) { char *address=strDest; assert((strDest != NULL) && (strScr != NULL)); while(*strScr) //是while(*strScr != ’\0’)的简化形式; { *strDest++ = *strScr++; } *strDest = '\0'; //当strScr字符串长度小于原strDest字符串长度return address; //时,如果没有改语句,就会出错了。 } 以下是在VC6.0中调试的例子,函数名用strcpya代替。 #include function F = ztrans(varargin) %ZTRANS Z-transform. % F = ZTRANS(f) is the Z-transform of the scalar sym f with default % independent variable n. The default return is a function of z: % f = f(n) => F = F(z). The Z-transform of f is defined as: % F(z) = symsum(f(n)/z^n, n, 0, inf), % where n is f's symbolic variable as determined by FINDSYM. If % f = f(z), then ZTRANS(f) returns a function of w: F = F(w). % % F = ZTRANS(f,w) makes F a function of the sym w instead of the % default z: ZTRANS(f,w) <=> F(w) = symsum(f(n)/w^n, n, 0, inf). % % F = ZTRANS(f,k,w) takes f to be a function of the sym variable k: % ZTRANS(f,k,w) <=> F(w) = symsum(f(k)/w^k, k, 0, inf). % % Examples: % syms k n w z % ztrans(2^n) returns z/(z-2) % ztrans(sin(k*n),w) returns sin(k)*w/(1-2*w*cos(k)+w^2) % ztrans(cos(n*k),k,z) returns z*(-cos(n)+z)/(-2*z*cos(n)+z^2+1) % ztrans(cos(n*k),n,w) returns w*(-cos(k)+w)/(-2*w*cos(k)+w^2+1) % ztrans(sym('f(n+1)')) returns z*ztrans(f(n),n,z)-f(0)*z % % See also IZTRANS, LAPLACE, FOURIER. % Copyright 1993-2003 TheMathWorks, Inc. % $Revision: 1.20.4.2 $ $Date: 2004/04/16 22:23:22 $ % Trap for errors in input first. ifnargin>= 4 error('symbolic:sym:ztrans:errmsg1','ZTRANS can take at most 3 input variables'); end % Make f a sym and extract the variable closest to 'x'. f = sym(varargin{1}); % Find all symbolic variables in f. vars = [ '{' findsym(f) '}' ]; % Determine whether n is in the expression. varcheck = maple([ vars ' intersect {n}']); % If n is a symbolic variable, make it the default. Otherwise % let the variable closest to x be the variable of integration. ifisequal(varcheck,'{n}') var = sym('n');strlen,strcat,strcpy,strncpy,strcmp函数的比较
编写strcpy函数和类String的构造函数、析构函数、赋值函数和重载运算符函数
各种字符串处理函数示例(基本)
C++中strcpy函数的几种实现和解析
C++常用库函数atoi,itoa,strcpy.strcmp的实现
strcpy的用法
二级c常用函数总结(1)
Strcpy函数介绍
字符串处理函数大全
strncpy函数的用法
strcpy函数
C语言常用函数名及用法
strcmp()函数的使用问题
OC常用函数
用C语言实现strcpy,strncpy,strcat,strcmp,strlen函数
Strcat,strcpy,strcmp,Strlen函数原型
ztrans函数