我试图使用ofstream的open(...)来打开一个用C ++编写的文件。出于某种原因,如果我使用从字符串流构建的char *或字符串,它将失败。换句话说,我的ofstream对象的fail()函数返回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";
这打印&#39;失败&#39;控制台。我已经使用调试器验证了logPath实际指向正确的预期字符串;是的,如果我做一个cout&lt;&lt;就在stream.open行之前,它也会打印到控制台的正确路径,例如:
C:\Logs\2015:01:15:18:34:10.txt
但是打开(...)仍然会翻转失败状态,我无法写入文件。但是,如果我用字符串文字填充logPath,例如
char * logPath = "c:\\logs\\log.txt";
然后它有效。此外,显然如果我将一个带有我的路径的字符串文字直接放入open(...),那么它就可以了。
使用时间戳生成器时也会失败:
stream.open(ss.str().c_str(), ios::out | ios::app);
为什么呢?如何从字符串流中获取C string / char *,这是一个流开放(...)调用可以读取的?注意,这也会导致失败状态:
stream.open(ss.str(), ios::out | ios::app);
此外,如果我使用append命令构建一个字符串,那也会失败。 E.g:
string path;
path.append(DIRECTORY_PATH);
path.append(generateTimestamp());
path.append(".txt");
stream.open(path, ios::out | ios::app);
这失败了,但是当我调试或打印到控制台(例如cout&lt;&lt; path)时,我得到了预期的路径:
C:\Logs\2015:01:15:18:34:10.txt
我错过了什么?
答案 0 :(得分:2)
简单的回答,我的字符串是由一个函数生成的,该函数包含了Windows文件名中非法的字符,我在深夜的疲惫中忽略了它。
对于后代的更长的答案,我正在使用的字符串的一部分作为我的文件路径正在从返回冒号的时间戳生成函数中读取:&#39;:&#39;作为时间戳的一部分。该函数用于控制台输出,但我试图用它来生成文件名。当然,Windows不允许使用冒号:&#39;在文件名中。