如何连接str和int ptr

How do I concatenate a str and a int ptr

本文关键字:str int ptr 连接 何连接      更新时间:2023-10-16

我的文件名需要一个char*。应该是这样的:cards/h11.bmp

我有一个从SO的各种文章中拼凑出来的函数:

char* getFileName(int* pc1_no, char* suite)
{
int number;
char pCard1[80];
strcpy_s(pCard1, "cards/");
strcat_s(pCard1, suite);
number = *pc1_no;
cout << number << endl;
string str = to_string(number);
char const *pchar = str.c_str();
strcat_s(pCard1, pchar);
strcat_s(pCard1, ".bmp");
return pCard1;
}

当然,这会返回垃圾。我不太明白指针的值。我确信我的指针犯了一个愚蠢的错误。提前谢谢。

实现这一切的最佳方法是去掉所有指针,并始终使用字符串:

std::string getFileName(int pc1_no, 
const std::string & suite)
{
std::string pCard1 = "cards/" + suite + std::to_string(pc1_no) + ".bmp";
return pCard1;
}

或者如果按照std::to_string不可用的旧C++标准构建:

std::string getFileName(int pc1_no, 
const std::string & suite)
{
std::stringstream pCard1;
pCard1<< "cards/" << suite << pc1_no << ".bmp";
return pCard1.str();
}

理性

char pCard1[80];

是一个局部变量。它将在函数结束时死亡,因此函数返回一个指向无效内存的指针。结果会发生很多不好的事情,很少有好的事情发生。小心少数好人。他们是骗子,在等待最合适的时机发动攻击。

维护OP结构的最简单的解决方案是使用std::string在函数内部执行字符串操作。

std::string getFileName(int* pc1_no, char* suite)
{
std::string pCard1 = "cards/";
pCard1 += std::string(suite);
pCard1 += std::to_string(*pc1_no);
pCard1 += std::string(".bmp");
return pCard1;
}

以上是可怕的代码,既过于冗长又效率低下,但我们已经在介绍中介绍了正确的方法。这只是通往正确道路的一个逻辑起点。

更快、更不复杂的是利用std::stringstream在没有任何外部帮助的情况下格式化c样式字符串和数字的能力。在std::to_string在C++11标准中可用之前,这种方法可能是最好的。

std::string getFileName(int* pc1_no, char* suite)
{
std::stringstream pCard1;
pCard1<< "cards/" << suite << *pc1_no << ".bmp";
return pCard1.str();
}

按值返回string可能会导致性能损失,但过去几十年的编译器善于检测并利用机会省略不必要的复制,并在幕后使用移动语义。

按值返回string也远不如动态分配存储并将存储返回给调用者并期望调用者释放它容易出错。任何可能留下的性能损失都很可能是值得的。对代码进行分析以确定。

改进函数调用:

pc1_no作为指针传入毫无帮助。除非您需要修改函数内部的值,否则只需传递值即可。如果确实需要更改值,请选择引用。

std::string getFileName(int pc1_no, char* suite)

如果您尝试传递字符串文字:例如:

getFileName(&somenumber, "string literal");

字符串文字可能在不可写的内存中,并且在C++中总是CCD_ 10。将const值传递到可能试图更改该值的空间中是不正确的形式。在旧的C++标准下,这是允许与C向后兼容的,尽管它可能会生成警告,但在C++11标准之后是非法的。

如果您的函数不需要修改char数组的内容,而且不需要修改,那么最好将字符串标记为const,并允许编译器防止意外发生,无论您的编译器是否允许const对非const赋值:

std::string getFileName(int pc1_no, const char* suite)

如果您使用对const std::string的引用,您可能会有更多的通用性,因为它可以从const和非constchar数组隐式转换,并且允许程序的其余部分利用std::string的许多好处,而无需对c_strdata进行不必要的调用。

std::string getFileName(int pc1_no, 
const std::string & suite)

这让我们回到了这个答案的由来

以下是C++中的代码:

#include <string>
std::string getFileName(int* n, const std::string& suite) {
return "cards/" + suite + std::to_string(*n) + ".bmp";
}

更好的方法是按值取第一个参数(int n),并在必要时在调用站点取消引用。

char* getFileName(int pc1_no, char* suite)
{
static char pCard1[80]; // Guarantee safe pointer return
strcpy_s(pCard1, "cards/");
strcat_s(pCard1, suite);
string str = to_string(pc1_no);
char const *pchar = str.c_str();
strcat_s(pCard1, pchar);
strcat_s(pCard1, ".bmp");
return pCard1; // Now you don't lose the result.
}

或者你可以使用推荐的C++风格,这已经得到了答案。