您的位置:首页 > 编程语言 > C语言/C++

C/C++字符串,字符数组,字符指针及其相互静态拷贝与追加的安全问题解决方案(1)

2016-10-24 23:27 686 查看

前言

这是第一篇,将把一些基本概念注意点列明,代码都在vs2013测试过,读者如果想用,应该花点时间理解,而不是把注释全部去掉来运行。本篇知识讲解一下安全拷贝的问题及其解决方案,下一篇将介绍安全追加问题

代码及其注释讲解

/* c中由于要追求效率,所以字符串字符数组这类都是先划分好存储区域的 */
/* 注意以下写法 */
/*
char *str1; //字符指针,指向可变,指向内容不知道是常量还是变量(指向内容不知可不可改)
char *str2="abc";  //字符指针,指向字符串常量,指向内容不可改,指向可变
char str3[]="abc";  //字符数组,和str3[3]="abc"效果相同,str3指向内容可改变,但是str3指向不可改变
str2=str3;   //用字符指针指向字符数组,指向内容可改变,指向也可改变

//这种形式不太建议,因为会令编程更加不可控,无论怎么用strlen,都只能得出3,而不是4
//且如果作为函数参数,那么就算是用sizeof,也只是把它识别为指针,统一作为4
char str4[5] = "abc";
*/
/* 如果在这片内存区域里进行一些修改,那么就要考虑越界的问题 */
/* 另外,为了控制长度,应该采用推荐使用的字符串函数 */
/*
char *strncpy(                       //Returns strDest
char *strDest,                      //Destination string.
const char *strSource,              //Source string.
size_t count                        //Number of characters to be copied
);

char *strncat(                      //Returns a pointer to the destination string. No return value is reserved to indicate an error
char *strDest,                     //Null-terminated destination string.
const char *strSource,             //Null-terminated source string
size_t count                       //Number of characters to append
);

int _snprintf(                     //返回值比较复杂,自行查参考书
char *buffer,                     //Storage location for the output.
size_t count,                     //Maximum number of characters to store
const char *format [,             //Format-control string.
argument] ...
);

size_t strlen(                    //没有初始化字符串或字符数组来使用这个函数,其返回值是难以预知的
const char *str                   //Null-terminated string.
);

*/
/* 在使用这些函数时,应该加以封装来达到自己想要的效果 */

/****************************字符串安全拷贝**********************************************/
#define SIZE 5
/* 从简单入手 */
/* C CHAR[] TO C CHAR[] */
/* C CHAR*(指向的是常量) TO C CHAR[] */
char* my_strncpy(char *dest, char *source)
{
if (dest != 0 && source != 0)
{
int dlen = strlen(dest);
int slen = strlen(source);
if (dlen <= slen)
{
/* 如果目标字符串长度小于源字符串长度 */
/* 就把源字符串按从前往后的顺序,完全覆盖在目标字符串上 */
return strncpy(dest, source, dlen);
}
else
{
/* 如果目标字符串长度大于源字符串长度 */
/* 就把源字符串按从前往后的顺序,覆盖在目标字符串上 */
/* 保留目标字符串后面几位字符 */
return strncpy(dest, source, slen);
}
}
return 0;

}

/* 重载解决c++字符串转字符数组问题 */
char* my_strncpy(char *dest, string source)
{
if (dest != 0 && !source.empty())
{
int dlen = strlen(dest);
int slen = source.length();
if (dlen <= slen)
{
/* 如果目标字符串长度小于源字符串长度 */
/* 就把源字符串按从前往后的顺序,完全覆盖在目标字符串上 */
return strncpy(dest, source.c_str(), dlen);
}
else
{
/* 如果目标字符串长度大于源字符串长度 */
/* 就把源字符串按从前往后的顺序,覆盖在目标字符串上 */
/* 保留目标字符串后面几位字符 */
return strncpy(dest, source.c_str(), slen);
}
}
return 0;

}

int main()
{
/* 从简单入手 */
/* C CHAR[] TO C CHAR[] */
/* C CHAR*(指向的是常量) TO C CHAR[] */
char cchar1[4] = "abc";    //dest
char cchar2[3] = "de";     //source1
char cchar3[] = "fghiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";   //source2
char *str1 = "jk";     //source3
char *str2 = "lmnoooooooooooooooooooooooooooooooooooo";   //source4
//my_strncpy(cchar1, cchar2);
//my_strncpy(cchar1, cchar3);
//my_strncpy(cchar1, str1);
//my_strncpy(cchar1, str2);
//cout << cchar1 << endl;

/* 从字符数组到字符串(其实就类似一个指针)是简单的,直接赋值或者调用构造函数就可以了
string cppstr1 = cchar1;
string cppstr2(&cchar1[0], &cchar1[strlen(cchar1)]);
cout << cppstr1 << endl;
cout << cppstr2<<endl;*/

/* 字符串到字符数组的转化 */
char cchar4[] = "abcd";    //dest
string cppstr3 = "eturns a pointer to the destination string. No return value is reserved to indicate a"; //source1
string cppstr4 = "et";    //source2
cppstr3.c_str();   //这也是一种方式
//my_strncpy(cchar4, cppstr3);
my_strncpy(cchar4, cppstr4);
cout << cchar4 << endl;

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: