1

我在这里做错了什么?

称呼

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
}
4

2 回答 2

6

str.substr(found+1)返回一个临时 std::string的. 您在该临时上调用c_str()方法,并将返回的指针分配给. 当临时对象被销毁时(在),您的路径指向垃圾。 std::stringpath;

帮自己一个忙,使用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 字符串指针,就像在 Cprintf()函数中一样):

std::cout << ExtractFileName("c:\\some\\dir\\hello.exe");
于 2013-01-03T17:41:01.443 回答
5

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

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

尝试声明path为 a string,并让您的函数返回 astring而不是指针。

一般来说,char *当你也在使用std::string 类时,你应该避免使用 raw。这意味着您还应该避免使用printf; 改用std::iostream类。

于 2013-01-03T17:19:43.890 回答