我需要一个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;
}
Run Code Online (Sandbox Code Playgroud)
当然,返回垃圾.我没有得到指针值.我很确定我用指针犯了一个愚蠢的错误.提前致谢.
use*_*301 10
完成所有这些操作的最佳方法是删除所有指针并使用字符串:
std::string getFileName(int pc1_no,
const std::string & suite)
{
std::string pCard1 = "cards/" + suite + std::to_string(pc1_no) + ".bmp";
return pCard1;
}
Run Code Online (Sandbox Code Playgroud)
或者如果构建到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();
}
Run Code Online (Sandbox Code Playgroud)
char pCard1[80];
Run Code Online (Sandbox Code Playgroud)
是一个局部变量.它会在函数结束时死掉,因此函数返回一个指向无效内存的指针.结果可能会发生许多不好的事情,很少有好处.注意少数好处.他们是等待最合适的罢工时间的骗子.
维护OP结构的最简单的解决方案是使用a 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;
}
Run Code Online (Sandbox Code Playgroud)
以上是可怕的代码,既过于冗长又低效,但我们已经在介绍中介绍了正确的方法.这只是通向正确方式的逻辑进展的接触点.
更快,更简单的是利用在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();
}
Run Code Online (Sandbox Code Playgroud)
有可能性能损失返回string值,但过去几十年的编译器擅长检测并利用机会省略不必要的复制并在幕后使用移动语义.
string按值返回也比动态分配存储并将存储返回给调用者并且期望调用者释放它更容易出错.任何可能存在的性能损失很可能都是值得的.描述代码以确定.
改进函数调用:
传递pc1_no中作为一个指针是不以任何方式帮助.除非您需要修改函数内部的值,否则只需按值传递.如果您确实需要更改值,请选择参考.
std::string getFileName(int pc1_no, char* suite)
Run Code Online (Sandbox Code Playgroud)
如果您尝试传递字符串文字:例如:
getFileName(&somenumber, "string literal");
Run Code Online (Sandbox Code Playgroud)
字符串文字可能位于不可写的内存中,并且始终const char *使用C++.将const值传递到可能尝试更改值的空间是不好的形式.这允许在较旧的C++标准下向后兼容C,尽管它可能会产生警告,但在C++ 11标准之后是非法的.
如果您的函数不需要修改char数组的内容,而这不是,那么将字符串标记为是一个很好的做法,const并允许编译器防止意外,无论您的编译器是否允许const非const赋值:
std::string getFileName(int pc1_no, const char* suite)
Run Code Online (Sandbox Code Playgroud)
如果你使用对a的引用,你可能有更多的功能,const std::string因为它可以从两个const和非const char数组隐式转换,并允许你的程序的其余部分利用std::string没有不必要的调用c_str和的许多好处data.
std::string getFileName(int pc1_no,
const std::string & suite)
Run Code Online (Sandbox Code Playgroud)
这让我们回到了这个答案的来源.
以下是此代码在C++中的外观:
#include <string>
std::string getFileName(int* n, const std::string& suite) {
return "cards/" + suite + std::to_string(*n) + ".bmp";
}
Run Code Online (Sandbox Code Playgroud)
如果需要,更好的方法是通过值(int n)获取第一个参数,并在呼叫站点取消引用.