C++ 如何从已安装的文件夹c/c++;

C++ 如何从已安装的文件夹c/c++;,c++,c,C++,C,我正在使用VisualStudio,我有一个代码,它使用了几个文件,并为它制作了一个安装程序。如果用户将程序安装到代码中提到的目录(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, m

我正在使用VisualStudio,我有一个代码,它使用了几个文件,并为它制作了一个安装程序。如果用户将程序安装到代码中提到的目录(
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);
#include <Windows.h>
#include <ShlObj.h>
#pragma comment (lib, "shell32.lib")
如果用户将其安装到任何其他目录,它将停止工作。如何让程序从任何目录读取文件,或者有什么解决方案

如果一个“heheretics.txt”文件在您的程序目录中(或目录树附近的某个地方),您可以编写如下内容:

fopen("heretics.txt", "r") // to open file from current directory
fopen("..\\heretics.txt", "r") // to open file from parent directory
// and so on ;)

要使用相对路径而不是绝对路径(如上面的注释所述)。

如果要从应用程序的EXE文件所在的目录中读取文件,则需要在运行时确定该目录。不要将路径硬编码到源代码中,或者依赖于工作目录

要在Windows中执行此操作,可以调用,这将返回EXE文件的完全限定路径。然后,您需要从路径中删除EXE文件名(例如,使用),以提供目录

#include <Windows.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
然后,您可以将文件名附加到路径,如下所示:

PathAppend(szPath, TEXT("heretics.txt"));
然后,您可以将
szPath
作为完全限定路径传递到
fopen
或用于打开文件的任何函数

但是

您应该仔细考虑应用程序的目录是否是存储这些文件的最佳位置。

如果应用程序本身要写入文件(例如,使用新更改更新文件),或者用户可能想要编辑文件,则应用程序的目录是一个糟糕的地方。默认情况下,应用程序安装到“Program Files”目录中,用户没有编辑权限。与您的示例相同,在磁盘的根级别

相反,您应该保存其中一个“应用程序数据”文件夹中的文件。您有以下选择:

  • FOLDERID\u ProgramData
    (所有用户均可使用的全局程序数据目录)
  • FOLDERID\u LocalAppData
    (每用户程序数据目录,非漫游)
  • FOLDERID\u RoamingAppData
    (每用户程序数据目录,漫游)
这些神奇的名称是
KNOWNFOLDERID
常量,您可以将这些常量传递给以检索这些文件夹之一的路径。例如:

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);
#include <Windows.h>
#include <ShlObj.h>
#pragma comment (lib, "shell32.lib")

使用相对路径而不是绝对路径。我已经正确格式化了您的源代码。如果您在将来的代码中也这样做,堆栈溢出用户会很感激。如果您的实际源代码不是这样的,我强烈建议您开始这样做。在一行中使用不一致的大括号和多个语句只会给你自己带来灾难,并且容易激怒同事。谢谢你的格式化。它在我的代码中看起来不错,我只是在粘贴到这里时遇到了一些问题。这就是我一直在寻找的。谢谢。@monkeytrack很高兴听到(或读到;))。由于这个答案对您有所帮助,您可以通过单击它旁边的复选标记来接受它作为解决方案。这将给你们和回答问题的人带来一些声誉,并将问题标记为已解决。这不是必需的,但强烈建议使用。:-)这看起来可能有效,但它取决于工作目录是什么。而且工作目录不能保证是EXE文件的位置。在工作目录下存储数据可能比在上面更实际。例如,如果从C:\Programs\Foo运行程序,则不希望将数据存储在C:\Programs中。为了便于携带,请使用
/
作为路径分隔符
fopen(“data/heretics.txt”,“r”)
这真的很有趣。谢谢你的回答。我喜欢你的说法,并会进一步调查。