有没有办法创建一个控制台应用程序,询问输入数据(例如用户出生日期、最喜欢的食物等),并执行我对其进行编程的任何操作,并在关闭它时将这些数据存储在该 .exe 中?
这样,当我再次打开它时,所有这些数据仍然会保存在那里,所以我只需更新或修改它们即可。
有没有办法创建一个 [...] 程序来询问输入数据 [...] 然后在我关闭它时将这些数据存储在该 .exe 中?
没有简单的方法(但你不需要)。您想要的是与持久性和应用程序检查点有关。
在实践中,您可能希望将数据存储在文件中 - 而不是可执行文件 - (可能使用某种文本格式,如JSON)或某些数据库中(可能像某些sqlite一样简单,或与某些RDBMS交互,如PostGreSQL)。对于诸如生日和食物偏好之类的事情,sqlite数据库文件可能是个好方法(请参阅一些SQLite 教程)。努力设计好数据库模式。
这样,当我再次打开它时,所有这些数据仍然会保存在那里
如果您将它们保存在某个外部文件(可能是一个简单的文件)中,这些数据仍然会在那里myappdata.sqlite。如果该文件不存在,您可以轻松地设计程序来创建该文件(这种情况仅在您第一次运行程序时发生;在下次运行时,您的程序将在启动时成功从该外部文件读取该数据)。
在大多数当前操作系统(阅读本教科书以了解有关操作系统的更多信息)中,特别是 Windows、MacOSX、Linux、Android 等,可执行文件应该是只读的。并且它可能同时在多个 进程中运行(在这种情况下,会发生什么?想想ACID属性)。
通常的做法是将数据存储在可执行文件之外(大多数程序,包括文本处理器、编译器、网络浏览器……都在这样做)。您没有解释为什么要在可执行文件中存储一些数据,这样做是不寻常的,并且高度特定于操作系统和可执行格式(对于 Linux,请仔细研究elf(5) ...)
我建议将数据保存在一些可选文件(或数据库)中 - 它的文件路径可能有一些连线常量默认值等...在启动时,您检查该数据是否存在(例如,使用access (2)fopen POSIX,或者只是通过处理或等等的失败情况sqlite3_open......)。如果它不存在,则以某种方式初始化程序数据。在退出时(或节省时间),您写入该数据。顺便说一句,大多数程序都是这样做的。
请注意,在大多数操作系统和计算机上,软件不仅仅是单个可执行文件,而是更多(例如所需的库和依赖项、配置文件、数据文件、构建自动化脚本Makefile等)。它的安装是一个明确的技术过程(有时是一个相当复杂的过程),并且包管理器很有帮助。
我的感觉是,如果没有特定的动机,您甚至不应该尝试在可执行文件中(持久地)存储(可变)数据(它很复杂,很脆弱,因为操作系统和编译器以及构建链特定的,不寻常的,并且会打开漏洞)。
为了完整起见,某些程序实际上通过重写其可执行文件来写入一些数据。在 Linux 上,GNUemacs在其文件中这样做(实际上,仅在安装过程中)unexec.c(非常脆弱,因为操作系统和编译器特定),但该功能存在争议,并且可能会消失。
许多其他系统巧妙地处理正交持久性:SBCL有一些save-lisp-and-die原语(它通常将状态持久保存在其他一些“图像”文件中)。Poly/ML有一些export设施。J.Pitrat 的 CAIA 系统(请参阅本文和他的博客;经许可,可以在我的主页上找到 2016 年的 CAIA 压缩包)能够完全重新生成其所有 C 代码和所有所需数据(数千个文件)。FullPliant将其状态保存在组织良好的文件树中。此类持久性或检查点技术与垃圾收集相关(因此您应该阅读GC 手册),并且使用接近复制垃圾收集的技术和算法。
FWIW,我当前的项目bismon正交地保留其整个堆,但在主可执行文件之外执行此操作(在理想的世界中,我想重新生成它的所有 C 或 C++ 源代码;我还远远没有那个目标)。
我的建议是将您的软件保存在多个文件中:其可执行文件、与其相关的 C++ 源代码、其数据文件(可能还有更多依赖项,即共享库或 DLL、字体和图像文件、所需的二进制文件等... )。然后,在保留状态时,您不需要覆盖可执行文件。由于您提到了 C++ (不是同 形的),您可以使用其持久数据生成系统的 C++ 代码(然后称为Quine程序)(并将所有生成的 C++ 的重新编译留给系统的 C++ 编译器)。我还建议让你的自生成程序成为一些免费软件。(如果您这样做,请编辑您的问题以给出其 URL)。
在 C++ 中,您可以通过以下方式将数据保留在可执行文件中(同样,这是一个坏主意,我希望说服您避免这种方法):您添加一个 C 或 C++ 源文件(例如mydata.cc),其中包含只有数据(例如一些大数据const char data[]="... many lines of data ...";) - 顺便说一句,XBM文件格式可能会鼓舞人心。您保留所有其他*.o 目标文件(在您的程序已知的位置)。要保存数据,您可以在每次保存操作时重新生成该mydata.cc文件(使用当前状态的新数据),最后运行适当的命令(可能在代码中使用std::systemmydata.cc )来编译该文件并将其与保存*.o到新的可执行文件中。因此,每个保存操作都需要重新编译data.cc并与其他目标文件链接*.o(当然,C++ 编译器和链接器,也许还有其他构建自动化工具,成为程序所需的依赖项)。这种方法并不比保留外部数据文件简单(并且*.o无论如何都需要保留这些目标文件)。
这样,当我再次打开它时,所有这些数据仍然会保存在那里
如果您的目标只是获取过去写入的数据,只需将数据保存在一些可选的数据库或文件中(就像许多程序一样:如果您在没有启动它的情况下启动它,您的文字处理程序会要求您在退出之前保存其文档)任何文档并在其中写几句话)在可执行文件之外并在退出程序之前写入它。无需覆盖您的可执行文件!
| 归档时间: |
|
| 查看次数: |
3678 次 |
| 最近记录: |