从路径返回文件名

Pow*_*fet 1 c++

我在这做错了什么?

呼叫

printf(filename(exename));
Run Code Online (Sandbox Code Playgroud)

我的函数应该返回文件名

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
}
Run Code Online (Sandbox Code Playgroud)

Mr.*_*C64 6

str.substr(found+1)返回一个临时的 std::string. 您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;
}
Run Code Online (Sandbox Code Playgroud)

另请注意,您对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());
Run Code Online (Sandbox Code Playgroud)

...或者只是使用cout(它可以很好地使用std::string并且不需要c_str()方法调用来获取像在 Cprintf()函数中那样的原始 C 字符串指针):

std::cout << ExtractFileName("c:\\some\\dir\\hello.exe");
Run Code Online (Sandbox Code Playgroud)


ant*_*oft 5

您正在返回一个指向由临时持有的内存的指针(str.substr(found+1)).c_str().当临时超出范围时,可以随时覆盖内存.

str.substr(found+1)是一个返回a的表达式string.此对象是一个临时值,它将在包含它的表达式执行结束时消失.使用.c_str(),您将获得一个指向此对象控制的内存的指针.在对象的生命周期之后,此指针不再有效.

尝试声明path为a string,让函数返回string而不是指针.

一般来说,char *当你还在std::string 上课时,你应该避免使用raw .这意味着你也应该避免使用printf; std::iostream而是使用类.