【发布时间】:2014-01-28 04:00:19
【问题描述】:
在使用 MS Visual Studio 2003 从 C++ 编译的 DLL 中,我通过从 SHGetFolderPath 获取字符串并附加文件名来生成文件路径,然后尝试打开该文件进行输出。
我有一些全局变量,一个用于设置文件路径的函数,另一个用于打开文件的函数,如下所示。Logger 类声明未显示,但它有一个声明为 ofstream *ofs 的成员,这是在 Logger 的构造函数中创建的文件对象。
在constructorBase() 中,如果我调用initLogFN() 来设置文件路径,ofs->open 会失败。
但是,如果我注释掉 initLogFN() 调用并取消注释将 logPath 设置为硬编码字符串文字的行,ofs->open 会成功。
在任何一种情况下进行调试时,Visual Studio 都会在调用 ofs->open 之前正确地将 logPath 显示为具有值“C:\Users\sleis\AppData\Roaming\Address-IT.log”。
然而,在失败的情况下,在ofs->open 调用之后,logPath 的值更改为六个字符,这些字符看起来是随机的,但每次运行我的测试应用程序时都是相同的。
为什么这两种情况的行为不同,我该如何解决失败的情况?
#if defined (WIN32)
const char dirSep[]="\\";
#else
const char dirSep[]="/";
#endif
const char logFN[]="Address-IT.log";
char *logPath=0;
bool initLogFN()
{
if (logPath!=0) return false;
#if defined (_DEBUG)
#if defined (WIN32)
char path[MAX_PATH];
HRESULT result=SHGetFolderPath(NULL,CSIDL_APPDATA,NULL,SHGFP_TYPE_CURRENT,path);
if (result!=S_OK) return false;
strcat(path,dirSep);
strcat(path,logFN);
logPath=path;
return true;
#endif
#endif
return false;
}
void Logger::constructorBase()
{
if (!initLogFN()) return;
//logPath="C:\\Users\\sleis\\AppData\\Roaming\\Address-IT.log";
ofs->open(logPath,ios_base::out | ios_base::app);
if ((ofs->rdstate() & std::ifstream::failbit)!=0) {
std::cout << std::endl << "Error opening log file.";
} else if (ofs->is_open()) {
std::cout << std::endl << "Log file opened successfully.";
}
}
【问题讨论】: