strcpy()、strlen()、memcpy()、memmove()、memset()的實現
ios
strcpy(), 字符串拷貝.
char *strcpy(char *strDest, const char *strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != '\0')
NULL ;
return address ;
}
strlen,
c++
#include <iostream>小程序
using namespace std;數組
void itoaTest(int num,char str[] )安全
{函數
int sign = num,i = 0,j = 0;spa
char temp[11];指針
if(sign<0)//判斷是不是一個負數orm
{內存
num = -num;
};
do
{
temp[i] = num%10+'0';
num/=10;
i++;
}while(num>0);
if(sign<0)
{
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 <assert.h>
#include <string.h>
#include <iostream>
using namespace std;
char *srcpy(char *dest,const char *source)
{
assert((dest!=NULL)&&(source!=NULL));
char *address = dest;
while(*source!='\0')
{
*dest++=*source++;
}
*dest = '\0';
return address;
}
4.//判斷輸入的是不是一個迴文字符串
#include "stdafx.h"
#include <string.h>
#include <iostream>
using namespace std;
//方法一:藉助數組
bool isPalindrome(char *input)
{
char s[100];
strcpy(s,input);
int length = strlen(input);
int begin = 0,end = length-1;
while(begin<end)
{
if(s[begin]==s[end])
{
begin++;
end--;
}
else
{
break;
}
}
if(begin<end)
{
return false;
}
else
{
return true;
}
}
//方法二:使用指針
bool isPalindrome2(char *input)
{
if(input==NULL)
return false;
char *begin = input;
char *end = begin+strlen(input)-1;
while(begin<end)
{
if(*begin++!=*end--)
return false;
}
return true;
}
int main(int argc, char* argv[])
{
char *s ="1234554321";
if(isPalindrome(s))
{
cout<<"True"<<endl;
}
else
{
cout<<"Fasle"<<endl;
}
if(isPalindrome2(s))
{
cout<<"True"<<endl;
}
else
{
cout<<"Fasle"<<endl;
}
cin.get();
return 0;
}
5.//不使用庫函數,編寫函數int strcmp(char *source, char *dest),若相等返回0,不然返回-1
int strcmp(char *source, char *dest)
{
assert(source != NULL && dest != NULL);
while(*source++==*dest++)
{
if(*source=='\0'&&*dest=='\0')
return 0;
}
return -1;
}
ret = strcmp("aa", "aa"); //0
ret = _stricmp("aa", "AA"); //0
ret = strcmp("aa", "aad"); //-1
strcmp(s1,s2)與_stricmp(s1,s2)
相同點:處理的都是C格式的字串,若是比較C++格式的string類型字串時,可使用string.c_str()來轉換成C格式的字串再進行比較。
不一樣點:1)前者區分大小寫,後者不區分大小寫
2)前者返回-1,0,1,後者返回字串實際差值,即整形數:負數,零,正數
二:strcpy_s&&strcpy的比較
以下所示:
char szBuf[2] = {0};
strcpy_s(szBuf, 2, "12131"); //注意第二個參數是申清空間的大小
strcpy(szBuf, "12131");
上述代碼,明顯有緩衝區溢出的問題。 使用strcpy_s函數則會拋出一個異常。而使用strcpy函數的結果
則未定,由於它錯誤地改變了程序中其餘部分的內存的數據,可能不會拋出異常但致使程序數據錯誤,
也可能因爲非法內存訪問拋出異常。使用新的加強安全的CRT函數有什麼好處呢?簡單地說,新的函數
增強了對參數合法性的檢查以及緩衝區邊界的檢查,若是發現錯誤,會返回errno或拋出異常。
老版本的這些CRT函數則沒有那麼嚴格的檢查與校驗,若是錯誤地傳輸了參數或者緩衝區溢出,
那麼錯誤並不能被馬上發現,對於定位程序錯誤也帶來更大困難。
//--------------------strcpy,strcpy_s------------------------------------------
//原型:extern char *strcpy(char *dest,char *src);
//功能:把src所指由NULL結束的字符串複製到dest所指的數組中。
//說明:src和dest所指內存區域不能夠重疊且dest必須有足夠的空間來容納src的字符串,返回指向dest的指針。
//strcpy用法:
// 若源長<目標長 --->OK。
//將源串COPY至目標串(包括結尾符),其它字節保持不變,
//若源長>目標長 --->溢出報錯。
//將源串COPY至目標串(包括結尾符),但目標串過短,下標越界而溢出,不正常的字串顯然會在致使運行時異常,
//使用原則總結:使用時保證源長<目標長
//strcpy_s用法:
//若源長<目標長 sizeof([min, max])--->OK,但自定義拷貝的字串長度超過目標長度時,會因下標越界而致使運行異常
//若源長>目標長 sizeof任何一方都會發生運行異常,
//(有多是編譯器在copy前會先檢查二者長度,
//若是源串較長便會發生告警而退出,所以後續使用sizeof(strlen(strDest)=0)語句已無效)
//使用原則總結: 1,使用時保證:源長<目標長,2,長度不能超出szDest長度,建議使用sizeof(szDest)
#include <iostream>
#include <string>
using namespace std;
#define STRCPY_TEST 0
#define LEN_STR 15
void main()
{
char szDest[10];
char szSrc_shorter[] = "1234";
char szSrc_longer[] ="123456789012";
cout<<"char szDest[10];"<<endl;
cout<<"char szSrc_shorter[] = \"1234\";"<<endl;
cout<<"char szSrc_longer[] = \"123456789012345\";"<<endl;
#if (0 == STRCPY_TEST)
cout<<"\n[OK] strcpy(szDest, szSrc_shorter);\nstrDest[1~15] = ";
strcpy(szDest, szSrc_shorter);
for(int i = 0; i < LEN_STR; i++)
{
cout<<szDest[i]<<", ";
}
cout<<endl<<"szDest = "<<szDest<<endl;
strcpy(szDest, szSrc_longer);
cout<<"\n[NG] strcpy(szDest, szSrc_longer);\nstrDest[1~15] = ";
for(int i = 0; i < LEN_STR; i++)
{
cout<<szDest[i]<<", ";
}
cout<<endl<<"szDest = "<<szDest<<endl;
#else
cout<<"\n[OK] strcpy_s(szDest, sizeof(szSrc_shorter), szSrc_shorter);\nstrDest[1~15] = ";
strcpy_s(szDest, sizeof(szSrc_shorter), szSrc_shorter);
for(int i = 0; i < LEN_STR; i++)
{
cout<<szDest[i]<<", ";
}
cout<<endl<<"szDest = "<<szDest<<endl;
cout<<"[OK] strcpy_s(szDest, sizeof(szDest), szSrc_shorter);\nstrDest[1~15] = ";
strcpy_s(szDest, sizeof(szDest), szSrc_shorter);
for(int i = 0; i < LEN_STR; i++)
{
cout<<szDest[i]<<", ";
}
cout<<endl<<"szDest = "<<szDest<<endl;
cout<<"[NG] strcpy_s(szDest, sizeof(szSrc_longer), szSrc_longer);\nstrDest[1~15] = ";
strcpy_s(szDest, sizeof(szSrc_longer), szSrc_longer);
for(int i = 0; i < LEN_STR; i++)
{
cout<<szDest[i]<<", ";
}
cout<<endl<<"szDest = "<<szDest<<endl;
cout<<"\n[NG] strcpy_s(szDest, sizeof(szDest), szSrc_longer);\nstrDest[1~15] = ";
strcpy_s(szDest, sizeof(szDest), szSrc_longer);
szDest[sizeof(szDest) - 1] = 0;
for(int i = 0; i < LEN_STR; i++)
{
cout<<szDest[i]<<", ";
}
cout<<endl<<"szDest = "<<szDest<<endl;
#endif
}
輸出:(NG部分的輸出已無心義,能夠不看)
(1)STRCPY_TEST==0
char szDest[10];
char szSrc_shorter[] = "1234";
char szSrc_longer[] = "123456789012345";
[OK] strcpy(szDest, szSrc_shorter);
strDest[1~15] = 1, 2, 3, 4, , ? ? ? ? ? ? ? ? ? ?
szDest = 1234
[NG] strcpy(szDest, szSrc_longer);
strDest[1~15] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, , ? ?
(2)STR_CPY_TEST<>0
char szDest[10];
char szSrc_shorter[] = "1234";
char szSrc_longer[] = "123456789012345";
[OK] strcpy_s(szDest, sizeof(szSrc_shorter), szSrc_shorter);
strDest[1~15] = 1, 2, 3, 4, , ? ? ? ? ? ? ? ? ? ?
szDest = 1234
[OK] strcpy_s(szDest, sizeof(szDest), szSrc_shorter);
strDest[1~15] = 1, 2, 3, 4, , ? ? ? ? ? ? ? ? ? ?
szDest = 1234
[NG] strcpy_s(szDest, sizeof(szSrc_longer), szSrc_longer);
strDest[1~15] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, , ? ?
szDest = 123456789012
[NG] strcpy_s(szDest, sizeof(szDest), szSrc_longer);
strDest[1~15] = 請按任意鍵繼續. . .
//-------------------------------memcpy-------------------------------------
// 原型:extern void *memcpy(void *dest, void *src, unsigned int count);
// 原理:由src所指內存區域複製count個字節到dest所指內存區域。
// 說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。
//strncpy() 是處理的字符串(遇零結束),
//memcpy() 是處理一個緩衝區(void*類型的),
//以字串類型的memcpy用法爲例:
//源長<目標長時,第3個參數使用任何一方的size,效果都同樣
//源長>目標長時,第3個參數用sizeof(strSrc),會形成下標越界,而使目標串溢出,從而致使運行異常
// 第3個參數用sizeof(strDest), 末尾字符(\0)沒有被COPY,輸出字串會有亂碼,
// 但不會運行異常,若是不考慮完整性,可使用strDest[sizeof(strDest)-1]=0截取前半部
//使用原則總結:1)保證源長<目標長;2)第3個參數推薦使用sizeof(strDest) 另外若是字串是指針要考慮一下sizeof的反作用
#include <iostream>
#include <string>
using namespace std;
void main()
{
char szSrc_shorter[] = "Good";
char szSrc_longer[] = "Have a Good Day!";
char szDest[10];
cout<<"char szSrc_shorter[] = \"Good\";"<<endl;
cout<<"char szSrc_longer[] = \"Have a Good Day!\";"<<endl;
cout<<"char szDest[10];"<<endl<<endl;
memcpy(szDest, szSrc_shorter, sizeof(szSrc_shorter));//<=>
//memcpy(szDest, szSrc_shorter, sizeof(szDest));
cout<<"[OK] memcpy(szDest, szSrc_shorter, sizeof(szSrc_shorter));";
cout<<"<=>\n[OK] memcpy(szDest, szSrc_shorter, sizeof(szDest));\nszDest[0~20] = \n";
for (int i = 0; i < 20; i++)
cout<<szDest[i]<<", ";
cout<<endl<<"szDest = "<<szDest<<endl;
memcpy(szDest, szSrc_longer, sizeof(szDest));
cout<<"\n[OK] memcpy(szDest, szSrc_longer, sizeof(szDest));\nszDest[sizeof(szDest) - 1] = 0; \nszDest[0~20] = \n";
szDest[sizeof(szDest) - 1] = 0;
for (int i = 0; i < 20; i++)
cout<<szDest[i]<<", ";
cout<<endl<<"szDest = "<<szDest<<endl;
memcpy(szDest, szSrc_longer, sizeof(szSrc_longer));
cout<<"\n[NG] memcpy(szDest, szSrc_longer, sizeof(szSrc_longer));\nszDest[sizeof(szDest) - 1] = 0; \nszDest[0~20] = \n";
szDest[sizeof(szDest) - 1] = 0;
for (int i = 0; i < 20; i++)
cout<<szDest[i]<<", ";
cout<<endl<<"szDest = "<<szDest<<endl;
}
輸出:(NG部分的輸出沒有意義,能夠不看):
char szSrc_shorter[] = "Good";
char szSrc_longer[] = "Have a Good Day!";
char szDest[10];
[OK] memcpy(szDest, szSrc_shorter, sizeof(szSrc_shorter));<=>
[OK] memcpy(szDest, szSrc_shorter, sizeof(szDest));
szDest[0~20] =
G, o, o, d, , ?.....?(15個?)
szDest = Good
[OK] memcpy(szDest, szSrc_longer, sizeof(szDest));
szDest[sizeof(szDest) - 1] = 0;
szDest[0~20] =
H, a, v, e, , a, , G, o, , ? ...?(10個?)
szDest = Have a Go
[NG] memcpy(szDest, szSrc_longer, sizeof(szSrc_longer)); szDest[sizeof(szDest) - 1] = 0; szDest[0~20] = H, a, v, e, , a, , G, o, , d, , D, a, y, !, , ? ? ? szDest = Have a Go