为什么 strcat_s 造成问题
why strcat_s causing problems
我遇到的问题是我得到的是随机字符输出,而不是得到名字、中间名和姓氏的组合,这是程序的目的,当我 运行 调试器时,它说问题在 strcat_s 但我不知道它有什么问题
#include <iostream>
#include <string.h>
class name {
private:
char first[20], mid[20], last[20];
public:
name();
name(const char*, const char*, const char*);
~name();
char* show();
};
name::name()
{
first[0] = mid[0] = last[0] = '[=11=]';
}
name::name(const char* f, const char* m, const char* l)
{
size_t lenF = strlen(f), lenM = strlen(m), lenL = strlen(l);
if (strlen(f) > 20) lenF = 20;
else if (strlen(m) > 20) lenM = 20;
else if (strlen(l) > 20) lenL = 20;
strncpy_s(first, f, lenF);
strncpy_s(mid, m, lenM);
strncpy_s(last, l, lenL);
}
name::~name()
{
std::cout << "distructing..." << std::endl;
}
char* name::show()
{
char temp[62];
strcpy_s(temp, first);
strcat_s(temp, " ");
strcat_s(temp, mid);
strcat_s(temp, " ");
strcat_s(temp, last);
return temp;
}
int main()
{
name a("kinan", "fathee", "ayed");
std::cout << a.show() << std::endl;
}
应该为'\0'保留1个字符,所以你需要写strncpy_s(first, f, lenF - 1);
您return输入全名的逻辑不正确。您有一个局部变量 temp
并且您正在 return 引用该变量。但是,一旦 show()
函数完成,这个变量就会被销毁。所以,在你的 main
函数中你有一个引用,但它指向已经被破坏的东西。这就是为什么您在打印时会看到随机字符的原因。这是您的问题的解决方案。您需要创建一个动态数组,即指针,这样它就不会被破坏。
char *name::show()
{
int size = strlen(first) + strlen(mid) + strlen(last) + 3;
char *temp = new char[size];
strcpy_s(temp, size, first);
strcat_s(temp, size, " ");
strcat_s(temp, size, mid);
strcat_s(temp, size, " ");
strcat_s(temp, size, last);
return temp;
}
int main()
{
name a("kinan", "fathee", "ayed");
char *temp = a.show();
std::cout << temp << std::endl;
delete[] temp;
}
编辑:在您的原始代码中,如果您在 return 之前在 show
函数末尾打印 temp
,您将看到 temp
包含完整名字.
编辑:Temp 是局部变量。每个局部变量都在函数执行结束时被销毁。在建议的解决方案中,我在堆上动态创建一个数组。当我们动态创建一个数组时,它不会自动从堆中移除。因此,当我 return 对该数组的引用并在 main 中使用它时,它仍然有效。
编辑:
我在 main
函数中添加了 delete[]
来释放内存。
我遇到的问题是我得到的是随机字符输出,而不是得到名字、中间名和姓氏的组合,这是程序的目的,当我 运行 调试器时,它说问题在 strcat_s 但我不知道它有什么问题
#include <iostream>
#include <string.h>
class name {
private:
char first[20], mid[20], last[20];
public:
name();
name(const char*, const char*, const char*);
~name();
char* show();
};
name::name()
{
first[0] = mid[0] = last[0] = '[=11=]';
}
name::name(const char* f, const char* m, const char* l)
{
size_t lenF = strlen(f), lenM = strlen(m), lenL = strlen(l);
if (strlen(f) > 20) lenF = 20;
else if (strlen(m) > 20) lenM = 20;
else if (strlen(l) > 20) lenL = 20;
strncpy_s(first, f, lenF);
strncpy_s(mid, m, lenM);
strncpy_s(last, l, lenL);
}
name::~name()
{
std::cout << "distructing..." << std::endl;
}
char* name::show()
{
char temp[62];
strcpy_s(temp, first);
strcat_s(temp, " ");
strcat_s(temp, mid);
strcat_s(temp, " ");
strcat_s(temp, last);
return temp;
}
int main()
{
name a("kinan", "fathee", "ayed");
std::cout << a.show() << std::endl;
}
应该为'\0'保留1个字符,所以你需要写strncpy_s(first, f, lenF - 1);
您return输入全名的逻辑不正确。您有一个局部变量 temp
并且您正在 return 引用该变量。但是,一旦 show()
函数完成,这个变量就会被销毁。所以,在你的 main
函数中你有一个引用,但它指向已经被破坏的东西。这就是为什么您在打印时会看到随机字符的原因。这是您的问题的解决方案。您需要创建一个动态数组,即指针,这样它就不会被破坏。
char *name::show()
{
int size = strlen(first) + strlen(mid) + strlen(last) + 3;
char *temp = new char[size];
strcpy_s(temp, size, first);
strcat_s(temp, size, " ");
strcat_s(temp, size, mid);
strcat_s(temp, size, " ");
strcat_s(temp, size, last);
return temp;
}
int main()
{
name a("kinan", "fathee", "ayed");
char *temp = a.show();
std::cout << temp << std::endl;
delete[] temp;
}
编辑:在您的原始代码中,如果您在 return 之前在 show
函数末尾打印 temp
,您将看到 temp
包含完整名字.
编辑:Temp 是局部变量。每个局部变量都在函数执行结束时被销毁。在建议的解决方案中,我在堆上动态创建一个数组。当我们动态创建一个数组时,它不会自动从堆中移除。因此,当我 return 对该数组的引用并在 main 中使用它时,它仍然有效。
编辑:
我在 main
函数中添加了 delete[]
来释放内存。