我在这里做错了什么?
呼叫
printf(filename(exename));
我的函数应该返回文件名
const char* filename(const string& str)
{
const char* path;
size_t found;
found=str.find_last_of("/\\");
path = (str.substr(found+1)).c_str();
cout << str.substr(found+1); // ------------> is name ok
printf("\n\n");
printf(path); // ------------> is name not ok random numbers
printf("\n\n");
return path; // ------------> is not ok random numbers
}
答案 0 :(得分:5)
您正在返回指向由临时(str.substr(found+1)).c_str()
持有的内存的指针。当临时超出范围时,可以随时覆盖内存。
str.substr(found+1)
是一个返回string
的表达式。此对象是一个临时值,它将在包含它的表达式执行结束时消失。使用.c_str()
,您将获得一个指向此对象控制的内存的指针。在对象的生命周期之后,该指针不再有效。
尝试将path
声明为string
,并让您的函数返回string
而不是指针。
通常,在使用char *
课程时,应避免使用原始std::string
。这意味着你也应该避免使用printf
;改为使用std::iostream
类。
答案 1 :(得分:3)
str.substr(found+1)
会返回临时 std::string
。
您在 temporary c_str()
上调用std::string
方法,并将返回的指针指定给path
。
当临时被销毁时(在;
),你的路径指向垃圾。
帮自己一个忙,并使用 C ++ (不是C与C ++混合),使用健壮的字符串类(如std::string
)来存储字符串(而不是原始的潜在悬挂char*
指针):
std::string FileName(const std::string& str)
{
size_t found = str.find_last_of("/\\");
std::string path = str.substr(found+1); // check that is OK
return path;
}
另请注意,使用path
变量名称会让人感到困惑,因为函数似乎返回文件名(而不是路径)。
更简单的重写(没有path
变量):
std::string ExtractFileName(const std::string& fullPath)
{
const size_t lastSlashIndex = fullPath.find_last_of("/\\");
return fullPath.substr(lastSlashIndex + 1);
}
printf("Filename = %s\n", ExtractFileName("c:\\some\\dir\\hello.exe").c_str());
...或者只使用cout
(与std::string
配合使用,并且不需要c_str()
方法调用来获取C {{1}中的原始C字符串指针功能):
printf()