1.注意#include "../Common/MyTD.h" 这里面的目录表示方式与
CFile saveFile;
saveFile.Open(_T("\\abc.bmp"),CFile::modeCreate|CFile::modeNoTruncate|CFile::modeReadWrite);
这两种路径表达方式是不一样的。
2.
绝对路径:_T(“D:\\Project\\imageTest\\ImageRecognition.bmp”)
当前目录:_T(“ImageRecognition.bmp”)
上级目录:_T(“..\\ImageRecognition.bmp”)
上级目录下的子目录:_T(“..\\子目录文件夹\\ImageRecognition.bmp”)
但是这种方法并不好,因为这种方法是不稳定的。如果程序一运行就使用这种方法来访问程序根目录,一般不会出错。但一旦在程序运行过程中调用了文件打开对话框,那么默认目录就会改变为打开文件的目录地址,这时候若依然这样来访问,就会出错。所以推荐使用方法3来访问根目录。
同时注意,_T(“\\ImageRecognition.bmp”)这样的访问方式编译可以通过并且程序运行不会报错。但是这样是不会访问到正确的文件的。
3.获取当前exe文件所在目录。这样获取到的是一个绝对路径
CString rootFilePath;
TCHAR rfPath[MAX_PATH];
::GetModuleFileName(NULL, rfPath, MAX_PATH);
(_tcsrchr(rfPath, '\\'))[1] = 0; //去掉可执行文件名,(_tcsrchr(rfPath,'\\')指向了“\\”的字符地址
rootFilePath.Format(_T("%s"), rfPath);
解析:
A. MAX_PATH 是系统自定义的一个宏,其大小为260
#define MAX_PATH 260
B.
DWORD GetModuleFileName(HMODULE hModule,
LPTSTR lpFilename,
DWORD nSize
);
函数参数说明:
hModule HMODULE 装载一个程序实例的句柄。如果该参数为NULL,该函数返回该当前应用程序全路径。
lpFileName LPTSTR 是你存放返回的名字的内存块的指针,是一个输出参数。
nSize DWORD ,装载到缓冲区lpFileName的最大值。
C.
(_tcsrchr(rfPath,'\\'))[1]=0;
这行代码可以分解为两部分:
CHAR* lPath = _tcsrchr(rfPath, '\\');
lPath[1] = 0;
首先,_tcsrchr(rfPath,'\\');的作用是在rfPath字符串中寻找最后一个'\\'的位置。找到后返回该位置。于是lPath中存储的就是指向最后一个'\\'的指针,也就是指向左边的那条\。
然后,lPath[1] = 0;由于lPath指向左边的\,所以lPath[1]就是右边的\的位置,这行代码的作用是将右边的\改成0。从而最后一个'\\'就变成了'\0'。
而字符串是以'\0'结尾的。所以编译器会认为该字符串到这里就结束了。从而在之后的赋值中到这里就会结束。
例:
在项目根目录imageTest文件夹下有一张名为dest.bmp的位图:
D:\\Project\\imageTest\\dest.bmp
现在想要获取该根目录地址D:\\Project\\imageTest
先调用GetModuleFileName()函数,获取exe文件的地址:
_T(“D:\\Project\\imageTest\\ImageRecognition.exe”)
然后调用(_tcsrchr(rfPath,'\\'))[1]=0;将最后一个\改为0:
_T(“D:\\Project\\imageTest\0ImageRecognition.exe”)
由于编译器将\0作为字符串结束标志,故调用
rootFilePath.Format(_T("%s"),rfPath);
来将字符串内容赋值给rootFilePath的时候,赋值的内容是
_T(“D:\\Project\\imageTest”)
从而得到了根目录。