写一个常量字符串复制函数
我们以为的方式
写不了,我们把指针指向了这个常量区,看似拥有了,其实不属于str
我们需要把常量字符拿出来,让指针指向栈区或者堆区
#include<iostream>
using namespace std;
int clen(const char* str) {
int len = 0;
for (int i = 0; str[i]; i++) len++;
return len;
}
char* cstr(const char* str) {
int len = clen(str);
char strRt[0x20];
memcpy(strRt, str, len);
return strRt;
}
int main() {
char* str = cstr("你好");
cout << str<<endl;
return 0;
}
结果依然出错,因为strRt这个字符数组为局部变量传不出来
解决办法1-利用堆
char* cstr(const char* str) {
int len = clen(str);
char *strRt = new char[len];
memcpy(strRt, str, len);
return strRt;
}
解决办法2-将char数组定义为全局变量
char strRt[0x20];
char* cstr(const char* str) {
int len = clen(str);
memcpy(strRt, str, len);
return strRt;
}
现成的字符串复制函数
strcpy
#include <cstring> //都在这个头文件里面
int main()
{
char str1[20];
char str2[20];
std::cin.get(str2, 20);
std::strcpy(str1, str2); //将str2的内容赋值到str1
return 0;
}
但是strcpy是不安全的编译器会报warnning
两种方法可以解除
法一:\#pragma warning( disable : 4996)
法二:#define _CRT_SECURE_NO_WARNINGS
strcpy_s
strcpy_s(str1, str2); //将str2的内容赋值到str1
没得任何警告
如果str1用new来创建时,就会报错
char *str1 = new char[20];
这是因为strcpy_s()函数是有两个版本,用两个参数、三个参数都可以,只要可以保证缓冲区大小。
三个参数时:
errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
两个参数时:
errno_t strcpy_s( char (&strDestination)[size], const char *strSource ); // C++ 独属
若我们使用new来分配储存空间时,就会出现上面说的不能保证缓冲区大小的问题了
语法来说没有什么问题,但是因为str的储存空间是使用new临时分配的,所以并不能保证缓冲区大小,点击运行就会出现上述的错误了。
这种情况的解决方法其实很简单,那就是不符合2个参数的版本就使用3个参数的版本呗。在两个str之间,加上一个参数,标识长度。
char * str;
str = new char[20];
strcpy_s(str, strlen(str1)+1, str1);