BUGS9_strncpy函數拷貝長度不對

一、strcpy()與strncpy()

 strcpy():strcpy(dest,src);    strcpy把src所指向以'\0'結尾的字符串複製到dest所指的數組中,返回指向dest的指針。

 當sizeof(dest)>=sizeof(src)時,拷貝正確,並在dest字符串後面加入'\0';

 當sizeof(dest)<sizeof(src)時,拷貝出錯。




 strncpy():strncpy(dest,src,n);    strncpy把src所指向以'\0'結尾的字符串的前n個字符複製到dest所指的數組中,返回指向dest的指針。

 當n>=sizeof(src)時,拷貝正確,並在dest字符串後面加入'\0';

 當n<sizeof(src)時,只拷貝src前n-1個字符串到dest,不會爲dest字符串後面加入'\0';

使用wifimabager出現查看狀態不對

表現現象:當wifi名設置爲2個及以內的中文字符,一切正常,當設置爲3個及以上出現網絡連接正常,也可以正常上網,但是查看狀態卻一直是DISCONNECT.
分析:
執行wifid -t時會調用到 allwinner/wifimanager/src/core/wifimanager.c文件中aw_wifi_get_status()函數,裏面有一個對ssid的拷貝動作: strncpy(s->ssid,staInfo->ssid,strlen(staInfo->ssid)); 默認s->ssid的結構體長度設置太小了,中文名字受編碼不同長度又不一樣,所以出現拷貝時異常了.
wifimanager/src/core/include/wifi_intf.h @ -49,7 +49,7 @
enum wmgEvent{ WSE_PASSWORD_INCORRECT, };
-#define SSID_MAX 32
+#define SSID_MAX 64

示例代碼

#include<iostream>
#include<string>
 
using namespace std;
 
int main()
{
	char a[]="lanzhihui is a good boy!";
 
	//以下strcpy
	char b[30];
	char c[30];
	char d[30];
 
	strcpy(b,a);  //strcpy進行簡單的拷貝,除了拷貝a數組的字符串外,還會將a數組後面的'\0'拷貝給數組b.
 
	cout<<"b:"<<b<<endl;//當數組b的存儲空間 sizeof(b)>=sizeof(a) 時,正確拷貝,並在數組b字符串後加'\0'。
	                    //當數組b的存儲空間 sizeof(b)<sizeof(a) 時,拷貝出錯。
 
	cout<<"strlen(c):"<<strlen(strcpy(d,strcpy(c,a)))<<endl;//先是將a拷貝給c,strcpy返回c的地址,將c拷貝給d,並返回d的地址,再求字符串d的字符長度。
	                                                        //這是拷貝strcpy()函數拷貝完後,返回目標字符串地址的原因,可以支持鏈式表達等。 
	cout<<"c:"<<c<<endl;                                    
	cout<<"d:"<<d<<endl;
 
	//以下strncpy
	char e[10];
	char f[30];
	char g[30];
 
	strncpy(f,a,sizeof(f));  //sizeof(f)>=sizeof(a) 時,正確拷貝,
	strncpy(g,a,10);         //拷貝a中前9個字符到g中,必須手動爲g數組加入'\0'
	g[9]='\0';              //n<sizeof(a)時,必須有這一句,不然輸出出錯
	strncpy(e,a,sizeof(e));
	e[sizeof(e)-1]='\0';     //sizeof(e)<sizeof(a)時,必須有這一句,不然輸出出錯
	                         
	cout<<"e:"<<e<<endl;
	cout<<"f:"<<f<<endl;
	cout<<"g:"<<g<<endl;
 
 
	system("pause");
	return 0;
}

理解strcpy()與strncpy()函數拷貝以 ‘\0’ 結束:

#include<iostream>
#include<string>
 
using namespace std;
 
int main()
{
	char s[]="lanzhihui\0 is a good boy!";
	char name[30];
 
	strcpy(name,s);//拷貝以'\0'結束
 
	cout<<name<<endl;//輸出以'\0'結束
 
	strncpy(name,s,sizeof(name));//拷貝以'\0'結束
 
	cout<<name<<endl;//輸出以'\0'結束
 
	system("pause");
	return 0;
}

strcpy()與strncpy()實現

#include<iostream>
#include<string>
#include<assert.h>
 
using namespace std;
 
char *strcpy_m(char *dest,const char *str)  
{  
    assert((dest!=NULL)&&(str!=NULL));
	char *cp=dest;
    while((*cp++=*str++)!='\0')
	{
		//
	}
	return dest;
}  
 
char *strncpy_m(char *dest,const char *str,int n)
{
	assert((dest!=NULL)&&(str!=NULL));
	char *cp=dest;
	while(n&&(*cp++=*str++)!='\0')
	{
		n--;
	}
	if(n)
	{
		while(--n)
		*cp++='\0';
	}
	return dest;
}
 
int main()
{
	char a[]="lanzhihui is a good boy!";
 
	//以下strcpy_m
	char b[30];
	char c[30];
	char d[30];
 
	strcpy_m(b,a);  
 
	cout<<"b:"<<b<<endl;
 
	cout<<"strlen(c):"<<strlen(strcpy_m(d,strcpy_m(c,a)))<<endl;
	                                                        
	cout<<"c:"<<c<<endl;                                    
	cout<<"d:"<<d<<endl;
 
	//以下strncpy_m
	char e[10];
	char f[30];
	char g[30];
 
	strncpy_m(f,a,sizeof(f));  
	strncpy_m(g,a,10);         
	g[9]='\0';              
	strncpy_m(e,a,sizeof(e));
	e[sizeof(e)-1]='\0';     
	                         
	cout<<"e:"<<e<<endl;
	cout<<"f:"<<f<<endl;
	cout<<"g:"<<g<<endl;
 
 
	system("pause");
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章