当我传递从 stringstream 构建的 char 指针时,ofstream open(...) 失败

ofstream open(...) failing when I pass char pointer built from stringstream

我正在尝试使用 ofstream 的 open(...) 打开文件以用 C++ 编写。出于某种原因,如果我使用从字符串流构建的 char* 或字符串,它会失败。换句话说,我的 ofstream 对象的 fail() 函数 returns true(通过检查和控制台消息验证)。见下文:

stringstream ss;
ss << DIRECTORY_PATH;
// note, DIRECTORY_PATH is a string literal with correctly escaped backslashes
ss << generateTimestamp();
// generateTimestamp() returns a timestamp as a formatted char*
ss << ".txt";

char * logPath = (char*)malloc(sizeof(char) * strlen(ss.str().c_str()) + 1);
strcpy(logPath, ss.str().c_str();

ofstream stream;
stream.open(logPath, ios::out | ios::app);

if (stream.fail())
    cout << "fail";

这会将 'fail' 打印到控制台。我已经使用调试器验证了 logPath 实际上指向正确的预期字符串;是的,如果我在 stream.open 行之前执行 cout<<,它也会打印正确的控制台路径,例如:

C:\Logs15:01:15:18:34:10.txt

但是 open(...) 仍然翻转失败状态,我无法写入文件。但是,如果我用字符串文字填充 logPath,例如

char * logPath = "c:\logs\log.txt";

然后就可以了。此外,显然,如果我将带有路径的字符串文字直接放入 open(...) 中,那么它就可以工作了。

这在使用时间戳生成器时也会失败:

stream.open(ss.str().c_str(), ios::out | ios::app);

为什么?如何从 ofstream open(...) 调用可以读取的字符串流中获取 C string / char*?请注意,这也会导致失败状态:

stream.open(ss.str(), ios::out | ios::app);

此外,如果我使用追加命令构建字符串,也会失败。例如:

string path;
path.append(DIRECTORY_PATH);
path.append(generateTimestamp());
path.append(".txt");
stream.open(path, ios::out | ios::app);

这失败了,但是当我调试或打印到控制台时(例如 cout << 路径),我又得到了预期的路径:

C:\Logs15:01:15:18:34:10.txt

我错过了什么?

简单的回答,我的字符串是由一个函数生成的,该函数包含 Windows 文件名中的非法字符,而我在深夜的疲惫中忽略了它。

后代的更长答案,我用作文件路径的字符串的一部分是从时间戳生成函数中读取的,该函数返回冒号“:”作为时间戳的一部分。该函数用于控制台输出,但我试图用它来生成文件名。 Windows,当然,不允许在文件名中使用冒号':'。