从路径返回文件名

时间:2013-01-03 17:15:24

标签: c++

我在这里做错了什么?

呼叫

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
}

2 个答案:

答案 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()