【问题标题】:Passing const char * to file.open(), strange behavior [duplicate]将 const char * 传递给 file.open(),奇怪的行为 [重复]
【发布时间】:2017-04-08 20:22:07
【问题描述】:

下面的代码有问题。根据我使用的 IDE,我会遇到不同的行为。

Dev-C++: 运行良好。但是,如果我将GenerateFileName(0,0) 传递给file.open(),则不会创建任何文件。

Visual Studio 2013:在所有情况下都运行良好,但是生成的文件的名称看起来像

ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌPùD

或类似的东西,文件本身没有扩展名(我希望是 .txt 文件)。

int main()
{
    ofstream file;
    file.open(GenerateFileName(3, 0));
    file << 1 << endl;
    file.close();
    _getch();
}

const char* GenerateFileName(int Instance_nth, int Input_nth)
{
    string filename = to_string(Instance_nth);
    filename += "_";
    filename += to_string(Input_nth);
    filename += ".txt";

    return filename.c_str();
}

【问题讨论】:

  • GenerateFileName()中,变量filename在函数返回时被销毁,所以函数的返回值是垃圾。
  • 您正在返回一个指向局部变量的指针。那是UB。
  • 只需从函数中返回字符串
  • GenerateFileName的返回类型改为std::string
  • 在 C++11 中 ofstream::open can handle std::string 以及 const char *

标签: c++ c++11


【解决方案1】:
const char* GenerateFileName(int Instance_nth, int Input_nth)
{
    string filename = to_string(Instance_nth);
    filename += "_";
    filename += to_string(Input_nth);
    filename += ".txt";

    return filename.c_str();
}

您正在返回一个指向 filename 内部存储的数据的指针,而该数据以 GenerateFileName 的结尾被销毁:返回的值是一个悬空指针,您的代码是未定义的行为。

您可以做的是返回 std::string 而不是 const char*

std::string GenerateFileName(int Instance_nth, int Input_nth)
{
    string filename = to_string(Instance_nth);
    filename += "_";
    filename += to_string(Input_nth);
    filename += ".txt";

    return filename;
}

用法会变成:

file.open(GenerateFileName(3, 0).c_str());

【讨论】:

  • 谢谢。但我仍然想知道为什么代码在 Dev C++ 上运行良好(除了我将 GenerateFileName(0, 0) 传递给 file.open() 的场景)但在 Visual Studio 上却没有。
  • 未定义的行为 = 你不能指望它肯定能正常运行,但你也不能指望它肯定会崩溃。你的代码可能在某些编译器的某些版本上运行良好——看起来你的 Dev C++ 版本背后的编译器就是这种情况,但你可能在不同的编译器甚至是同一编译器的不同版本有不同的行为
【解决方案2】:

这是未定义的行为,因为filename 被销毁,一旦你离开GenenerateFileName 函数,file.open 正在接收指针,该指针指向已经被销毁的变量数据。

这里最简单的方法是从GenerateFileName 返回std::string 并执行类似file.open(GenerateFileName(0,0).c_str()); 的操作

【讨论】:

    猜你喜欢
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多