我正在使用Visual Studio,我有一个代码,它使用了几个文件并为它安装了一个安装程序。如果用户将程序安装到代码(c:\games
)中提到的目录,则一切正常。
例如:
FILE *myfile;
if ((myfile = fopen("c:\\games\\heretics.txt", "r")) == NULL) {
printf("Cannot Open File heretics.txt\n"); return -1;
}
while ( (fgets(p, 256, myfile)) != NULL ) {
printf("%s",p);
}
fclose(myfile);
如果用户将其安装到任何其他目录,它将停止工作。如何使程序从任何目录读取文件或可能是什么解决方案?
答案 0 :(得分:3)
如果“heretics.txt”文件位于程序目录中(或目录树中的某个位置),您可以编写如下内容:
fopen("heretics.txt", "r") // to open file from current directory
fopen("..\\heretics.txt", "r") // to open file from parent directory
// and so on ;)
使用相对路径而不是绝对路径(如上面评论中所述)。
答案 1 :(得分:3)
如果要从应用程序的EXE文件所在的目录中读取文件,则需要在运行时确定该目录。不要将路径硬编码到源代码中,也不要依赖于工作目录!
要在Windows中执行此操作,可以调用GetModuleFileName
function,它将返回EXE文件的完全限定路径。然后,您需要从路径中删除EXE文件名(例如,使用PathRemoveFileSpec
),以便为您提供目录。
#include <Windows.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
TCHAR szPath[MAX_PATH];
GetModuleFileName(NULL, szPath, MAX_PATH);
PathRemoveFileSpec(szPath);
然后,您可以将文件名附加到路径中,如下所示:
PathAppend(szPath, TEXT("heretics.txt"));
然后您可以将szPath
作为fopen
的完全限定路径或您用于打开文件的任何函数。
您应该仔细考虑应用程序的目录是否是存储这些文件的最佳位置。
如果应用程序本身要写入文件(例如,使用新更改更新它们),或者如果用户可能想要编辑它们,则应用程序的目录是一个糟糕的地方。默认情况下,应用程序安装在“Program Files”目录中,用户没有编辑权限。您的示例与磁盘的根级别相同。
相反,您应该保存其中一个“Application Data”文件夹中的文件。您有以下选择:
FOLDERID_ProgramData
(所有用户均可使用的全球程序数据目录)FOLDERID_LocalAppData
(每个用户程序数据目录,非漫游)FOLDERID_RoamingAppData
(每个用户程序数据目录,漫游)这些魔术名称是KNOWNFOLDERID
常量,您传递给SHGetKnownFolderPath
function以检索其中一个文件夹的路径。例如:
#include <Windows.h>
#include <ShlObj.h>
#pragma comment (lib, "shell32.lib")
// Retrieve the path.
PWSTR pszPath;
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_ProgramData,
0, // no special options required
NULL, // no access token required
&pszPath);
// Copy it into a local string.
TCHAR szPath[MAX_PATH];
lstrcpy(szPath, pszPath);
// Free the memory allocated by the SHGetKnownFolderPath function,
// so you don't accidentally leak it!
CoTaskMemFree(pszPath);