C语言字符串操作函数

C语言字符串操作函数

1. 写一个函数实现字符串反转

版本1 - while版

复制代码
void strRev( char * s)
{
char temp, * end = s + strlen(s) - 1 ;
while (end > s)
{
temp
= * s;
* s = * end;
* end = temp;
-- end;
++ s;
}
}
复制代码


版本2 - for版

复制代码
void strRev( char * s)
{
char temp;
for ( char * end = s + strlen(s) - 1 ;end > s; -- end, ++ s)
{
temp
= * s;
* s = * end;
* end = temp;
}
}
复制代码


版本3 - 不使用第三方变量

复制代码
void strRev( char * s)
{
for ( char * end = s + strlen(s) - 1 ;end > s; -- end, ++ s)
{
* s ^= * end;
* end ^= * s;
* s ^= * end;
}
}
复制代码


版本4 - 重构版本3

复制代码
void strRev( char * s)
{
for ( char * end = s + strlen(s) - 1 ;end > s; -- end, ++ s)
{
* s ^= * end ^= * s ^= * end;
}
}
复制代码


版本5 - 重构版本4

void strRev( char * s)
{
for ( char * end = s + strlen(s) - 1 ;end > s; * s ++ ^= * end ^= * s ^= * end -- );
}


版本6 - 递归版

复制代码
void strRev( const char * s)
{
if (s[ 0 ] == ' \0 ' )
return ;
else
strRev(
& s[ 1 ]);
printf(
" %c " ,s[ 0 ]);
}
复制代码



2. 实现库函数strcpy的功能

strcpy函数位于头文件<string.h>中

版本1

复制代码
strcpy( char * dest, const char * src)
{
char * p = dest;
while ( * dest ++ = * src ++ )
;
dest
= p;
}
复制代码


版本2

复制代码
char * __cdeclstrcpy( char * dst, const char * src)
{
char * p = dst;
while ( * p ++ = * src ++ )
;
return dst;
}
复制代码


版本3

复制代码
strcpy( char * dest, const char * src)
{
int i = 0 ;
for (; * (src + i) != ' \0 ' ;i ++ )
* (dest + i) = * (src + i);
* (dest + i) = ' \0 ' ;
}
复制代码



3. 实现库函数atoi的功能

atoi函数位于头文件<stdlib.h>中

版本1 - 附说明

复制代码
int power( intbase , int exp)
{
if ( 0 == exp)
return 1 ;
returnbase * power(base ,exp - 1 );
}

int __cdeclatoi( const char * s)
{
int exp = 0 ,n = 0 ;
const char * t = NULL;

for (; * s == ' ' || * s == ' \t ' || * s == ' \n ' ;s ++ ) // 找到第一个非空字符
;
if ( * s > ' 9 ' || * s < ' 0 ' ) // 如果第一个非空字符不是数字字符,返回0
return 0 ;

for (t = s; * t >= ' 0 ' && * t <= ' 9 ' ; ++ t) // 找到第一个非数字字符位置-方法1
;
t
-- ;

/* 找到第一个非数字字符位置-方法2
t=s;
while(*t++>='0'&&*t++<='9')
;
t-=2;
*/

while (t >= s)
{
n
+= ( * t - 48 ) * power( 10 ,exp); // 数字字符转化为整数
t -- ;
exp
++ ;
}
return n;
}
复制代码


版本2

复制代码
int __cdeclatoi( const char * s)
{
int exp = 0 ,n = 0 ;
const char * t = NULL;

for (; * s == ' ' || * s == ' \t ' || * s == ' \n ' ;s ++ ) // 略过非空字符
;
if ( * s > ' 9 ' || * s < ' 0 ' )
return 0 ;

for (t = s; * t >= ' 0 ' && * t <= ' 9 ' ; ++ t)
;
t
-- ;

while (t >= s)
{
n
+= ( * t - 48 ) * pow( 10 ,exp);
t
-- ;
exp
++ ;
}
return n;
}
复制代码



4. 实现库函数strlen的功能

strlen函数位于头文件<string.h>中

版本1 - while版

复制代码
size_t__cdeclstrlen( const char * s)
{
int i = 0 ;
while ( * s)
{
i
++ ;
s
++ ;
}
return i;
}
复制代码


版本2 - for版

size_t__cdeclstrlen( const char * s)
{
for ( int i = 0 ; * s;i ++ ,s ++ )
;
return i;
}


版本3 - 无变量版

复制代码
size_t__cdeclstrlen( const char * s)
{
if ( * s == ' \0 ' )
return 0 ;
else
return (strlen( ++ s) + 1 );
}
复制代码


版本4 - 重构版本3

size_t__cdeclstrlen( const char * s)
{
return * s ? (strlen( ++ s) + 1 ): 0 ;
}



5. 实现库函数strcat的功能

strcat函数位于头文件<string.h>中

版本1 - while版

复制代码
char * __cdeclstrcat( char * dst, const char * src)
{
char * p = dst;
while ( * p)
p
++ ;
while ( * p ++ = * src ++ )
;
return dst;
}
复制代码



6. 实现库函数strcmp的功能

strcmp函数位于头文件<string.h>中

版本1 - 错误的strcmp

复制代码
int strcmp( const char * a, const char * b)
{
for (; * a != ' \0 ' && * b != ' \0 ' ;a ++ ,b ++ )
if ( * a > * b)
return 1 ;
else if ( * a ==* b)
return 0 ;
else
return - 1 ;
}
复制代码


版本2

复制代码
int __cdeclstrcmp( const char * src, const char * dst)
{
int ret = 0 ;

while ( ! (ret = * (unsigned char * )src - * (unsigned char * )dst) && * src)
++ src, ++ dst;

if (ret < 0 )
ret
= - 1 ;
else if (ret > 0 )
ret
= 1 ;

return (ret);
}
复制代码



7. 计算字符串中元音字符的个数

复制代码
#include < stdio.h >

int is_vowel( char a)
{
switch (a)
{
case ' a ' : case ' A ' :
case ' e ' : case ' E ' :
case ' i ' : case ' I ' :
case ' o ' : case ' O ' :
case ' u ' : case ' U ' :
return 1 ; break ;
default :
return 0 ; break ;
}
}

int count_vowel( const char * s)
{
int num;
if (s[ 0 ] == ' \0 ' )
num
= 0 ;
else
{
if (is_vowel(s[ 0 ]))
num
= 1 + count_vowel( & s[ 1 ]);
else
num
= count_vowel( & s[ 1 ]);
}
return num;
}

int main()
{
char * s = " AobCdddudIe " ;
printf(
" %d\n " ,count_vowel(s));
return 0 ;
}
复制代码



8. 判断一个字符串是否回文:包含一个单词,或不含空格、标点的短语。如:Madam I'm Adam是回文

版本1

复制代码
/*
*程序功能:判断一个单词,或不含空格、标点符号的短语是否为回文(palindrome)
*/
#include
< stdio.h >
#include
< ctype.h >

int is_palindrome( const char * s)
{
bool is_palindrome = 0 ;
const char * end = s;

if ( * end == ' \0 ' ) /* 如果s为空串,则是回文 */
is_palindrome
= 1 ;

while ( * end) ++ end; /* end指向串s最后一个字符位置 */
-- end;

while (s <=end)
{
while ( * s == ' ' || ! isalpha( * s)) /* 略去串s中的非字母字符*/
++s;
while ( * end == ' ' || ! isalpha(*end))
--end;
if (toupper( * s) == toupper( * end)) /* 将s中的字母字符转换为大字进行判断*/
{
++s;
--end;
}
else
{
is_palindrome = 0 ;break;
} /* 在s<=end的条件下,只要出现不相等就判断s不是回文*/
}
if (s>end)
is_palindrome =1;
else
is_palindrome=0;
return(is_palindrome);

}

intmain()
{
const char * s = " MadamI'mAdam";
printf( " %s%s\n " ,s,is_palindrome(s) ? " isapalindrome! " : " isnotapalindrome!");
return0;
}
复制代码


趣的He lived as a devil, eh?

Don't nod
Dogma: I am God
Never odd or even
Too bad – I hid a boot
Rats live on no evil star
No trace; not one carton
Was it Eliot's toilet I saw?
Murder for a jar of red rum
May a moody baby doom a yam?
Go hang a salami; I'm a lasagna hog!
Satan, oscillate my metallic sonatas!
A Toyota! Race fast... safe car: a Toyota
Straw? No, too stupid a fad; I put soot on warts
Are we not drawn onward, we few, drawn onward to new era?
Doc Note: I dissent. A fast never prevents a fatness. I diet on cod
No, it never propagates if I set a gap or prevention
Anne, I vote more cars race Rome to Vienna
Sums are not set as a test on Erasmus
Kay, a red nude, peeped under a yak
Some men interpret nine memos
Campus Motto: Bottoms up, Mac
Go deliver a dare, vile dog!
Madam, in Eden I'm Adam
Oozy rat in a sanitary zoo
Ah, Satan sees Natasha
Lisa Bonet ate no basil
Do geese see God?
God saw I was dog
Dennis sinned


世界之最:世界上最长的回文包含了17,259个单词


说明:__cdecl,__stdcall是声明的函数调用协议.主要是传参和弹栈方面的不同.一般c++用的是__cdecl,windows里大都用的是__stdcall(API)

你可能感兴趣的:(c)