我需要找到一种方法在我的程序的可执行文件中存储250 KB的纯文本数字。如何将数据存储在可执行文件中
通常,我会把数据放在一个单独的文件中,让程序在运行时读取它,但这不是一个选项。相反,程序和数据需要在一个可执行文件中。
我绝对不知道该怎么做(除了写250.000 #defines :-),我会很感激任何建议。
我需要找到一种方法在我的程序的可执行文件中存储250 KB的纯文本数字。如何将数据存储在可执行文件中
通常,我会把数据放在一个单独的文件中,让程序在运行时读取它,但这不是一个选项。相反,程序和数据需要在一个可执行文件中。
我绝对不知道该怎么做(除了写250.000 #defines :-),我会很感激任何建议。
如何处理某种数组。只要把这个定义在文件中并编译成你的程序:
int external_data[] =
{
...
};
可以让编译器告诉你有多少元素在外部数据:
size_t external_data_max_idx = sizeof(external_data)/sizeof(*external_data);
+1使用空括号语法。 – 2010-04-11 18:46:04
+1用于在*独立*文件中建议定义。我目前正在使用这种技术,我只需要更改文件并重建,特别是当数据发生变化时。 – 2010-04-12 17:26:40
存储它作为一个常量数组:
/* Maximum number of digits in a number, adjust as necessary */
#define NUMBER_MAX_LENGTH 16
/* How many numbers you have (in this case 250K), adjust as necessary */
#define NUMBER_OF_NUMBERS (250 * (1 << 10))
const char data[NUMBER_OF_NUMBERS][NUMBER_MAX_LENGTH+1] =
{ "12345", "2342841", "129131", "18317", /* etc */ };
想必你知道你的数据集,所以你可以拿出你的情况为NUMBER_MAX_LENGTH
适当的值。
你当然也可以编写一个脚本,将一个数字的平面文件转换成这种格式。如果你愿意,你甚至可以将数字保存在纯文本数据文件中,并在构建过程中让脚本生成相应的C代码。
我是这样写的,因为你说“纯文本数字”,表明你需要它们作为字符串出于某种原因。如果你想让它们成为整数,那更简单:
/* How many numbers you have (in this case 250K), adjust as necessary */
#define NUMBER_OF_NUMBERS (250 * (1 << 10))
const int data[NUMBER_OF_NUMBERS] =
{ 12345, 2342841, 129131, 18317, /* etc */ };
假设你的数字都不是太大而不能存储在int中。
您可以使用'data []'而不是使用一些数字宏。 – 2010-04-11 18:45:17
这听起来像你想避免把它在源文件中,但是这确实是我会怎么做:
int numbers[250000] = {1, 2, ...};
这在技术上是可以将它们保存为纯文本文件,并编写创建一个新的d一个连接指令文件在一个合适的尺寸部分,并结合他们,但真的没有理由。把这个定义在一个单独的文件和#包括它变成了需要
请注意,你可以让“数字[]'和编译器会为你计算。 – 2010-04-11 18:42:49
是的,但是如果我知道我想包括它的数组中有多少东西,那么看着它的人都知道立即的大小,所以如果我搞砸了,忘记/重复一个我会得到一个编译时错误 – 2010-04-11 19:44:54
你可以适应this solution为数字文件:
static const wchar_t *systemList[] = {
L"actskin4.ocx",
L"advpack.dll",
L"asuninst.exe",
L"aswBoot.exe",
L"AvastSS.scr",
L"avsda.dll",
L"bassmod.dll",
L"browseui.dll",
L"CanonIJ Uninstaller Information",
L"capicom.dll",
L"cdfview.dll",
L"cdm.dll",
L"d3dx9_24.dll",
L"d3dx9_25.dll",
L"d3dx9_27.dll",
L"d3dx9_28.dll",
L"d3dx9_29.dll",
L"d3dx9_30.dll",
L"danim.dll",
L"dfrgntfs.exe",
L"dhcpcsvc.dll",
L"dllhost.exe",
L"dnsapi.dll",
L"drivers\\aavmker4.sys",
L"drivers\\apt.sys",
L"drivers\\aswFsBlk.sys",
L"drivers\\aswmon.sys",
L"drivers\\aswmon2.sys",
L"drivers\\aswRdr.sys",
L"drivers\\aswSP.sys",
L"drivers\\aswTdi.sys",
L"drivers\\avg7core.sys",
L"drivers\\avg7rsw.sys",
L"drivers\\avg7rsxp.sys",
L"drivers\\avgclean.sys",
L"drivers\\avgmfx86.sys",
L"drivers\\avgntdd.sys",
L"drivers\\avgntmgr.sys",
L"drivers\\avgtdi.sys",
L"drivers\\avipbb.sys",
L"drivers\\cmdmon.sys",
L"drivers\\gmer.sys",
L"drivers\\inspect.sys",
L"drivers\\klick.sys",
L"drivers\\klif.sys",
L"drivers\\klin.sys",
L"drivers\\pxcom.sys",
L"drivers\\pxemu.sys",
L"drivers\\pxfsf.sys",
L"drivers\\pxrd.sys",
L"drivers\\pxscrmbl.sys",
L"drivers\\pxtdi.sys",
L"drivers\\rrspy.sys",
L"drivers\\rrspy64.sys",
L"drivers\\ssmdrv.sys",
L"drivers\\UMDF",
L"drivers\\USBSTOR.SYS",
L"DRVSTORE",
L"dxtmsft.dll",
L"dxtrans.dll",
L"en-us",
L"extmgr.dll",
L"fntcache.dat",
L"hal.dll",
L"icardie.dll",
L"ie4uinit.exe",
L"ieakeng.dll",
L"ieaksie.dll",
L"ieakui.dll",
L"ieapfltr.dat",
L"ieapfltr.dll",
L"iedkcs32.dll",
L"ieframe.dll",
L"iepeers.dll",
L"iernonce.dll",
L"iertutil.dll",
L"ieudinit.exe",
L"ieui.dll",
L"imon1.dat",
L"inseng.dll",
L"iphlpapi.dll",
L"java.exe",
L"javaw.exe",
L"javaws.exe",
L"jgdw400.dll",
L"jgpl400.dll",
L"jscript.dll",
L"jsproxy.dll",
L"kbdaze.dll",
L"kbdblr.dll",
L"kbdbu.dll",
L"kbdkaz.dll",
L"kbdru.dll",
L"kbdru1.dll",
L"kbdtat.dll",
L"kbdur.dll",
L"kbduzb.dll",
L"kbdycc.dll",
L"kernel32.dll",
L"legitcheckcontrol.dll",
L"libeay32_0.9.6l.dll",
L"Macromed",
L"mapi32.dll",
L"mrt.exe",
L"msfeeds.dll",
L"msfeedsbs.dll",
L"msfeedssync.exe",
L"msftedit.dll",
L"mshtml.dll",
L"mshtmled.dll",
L"msrating.dll",
L"mstime.dll",
L"netapi32.dll",
L"occache.dll",
L"perfc009.dat",
L"perfh009.dat",
L"pncrt.dll",
L"pndx5016.dll",
L"pndx5032.dll",
L"pngfilt.dll",
L"px.dll",
L"pxcpya64.exe",
L"pxdrv.dll",
L"pxhpinst.exe",
L"pxinsa64.exe",
L"pxinst.dll",
L"pxmas.dll",
L"pxsfs.dll",
L"pxwave.dll",
L"rasadhlp.dll",
L"rasmans.dll",
L"riched20.dll",
L"rmoc3260.dll",
L"rrsec.dll",
L"rrsec2k.exe",
L"shdocvw.dll",
L"shell32.dll",
L"shlwapi.dll",
L"shsvcs.dll",
L"sp2res.dll",
L"spmsg.dll",
L"ssiefr.EXE",
L"STKIT432.DLL",
L"streamhlp.dll",
L"SWSC.exe",
L"tzchange.exe",
L"url.dll",
L"urlmon.dll",
L"vsdata.dll",
L"vsdatant.sys",
L"vsinit.dll",
L"vsmonapi.dll",
L"vspubapi.dll",
L"vsregexp.dll",
L"vsutil.dll",
L"vswmi.dll",
L"vsxml.dll",
L"vxblock.dll",
L"webcheck.dll",
L"WgaLogon.dll",
L"wgatray.exe",
L"wiaservc.dll",
L"windowspowershell",
L"winfxdocobj.exe",
L"wmp.dll",
L"wmvcore.dll",
L"WREGS.EXE",
L"WRLogonNtf.dll",
L"wrlzma.dll",
L"wuapi.dll",
L"wuauclt.exe",
L"wuaueng.dll",
L"wucltui.dll",
L"wups.dll",
L"wups2.dll",
L"wuweb.dll",
L"x3daudio1_0.dll",
L"xactengine2_0.dll",
L"xactengine2_1.dll",
L"xactengine2_2.dll",
L"xinput1_1.dll",
L"xinput9_1_0.dll",
L"xmllite.dll",
L"xpsp3res.dll",
L"zlcomm.dll",
L"zlcommdb.dll",
L"ZPORT4AS.dll"
};
我与以前的答案一致。最好的方法是将其存储在代码中,然后将其编译到程序中。 为了参数的缘故,您可以查看可执行文件的格式并在其中添加一些数据/代码(这是大量病毒的工作原理),并从可执行文件中读取数据并获取数据。 http://refspecs.freestandards.org/elf/elf.pdf具有可执行文件的格式。 这再次是为了争论,不建议。
让我们假设数字是常数。让我们假设,你可以在“预编译”阶段计算一次这个列表。让我们假设有一个函数可以“返回”该列表。
第一阶段: 编写调用getFooNumber()和作品完美的应用程序。尼斯。
第二阶段: 取出该函数,并将其放入另一个项目中。现在,让我们编写一个小程序,它将生成250,000行C代码。
#include <stdlib>
#define MAX_BLABLA 2500000
int main(int argc, char *argv[])
{
FILE *f fopen("fooLookupTable.h");
long i;
fprintf(f, "#ifndef FOO_HEADER\n");
fprintf(f, "#define FOO_HEADER\n");
fprintf(f, "char [] blabla = {\n\t");
for(i=0; i<MAX_BLABLA; i ++)
{
fprintf(f, "%d", getFooNumber(i));
if (n+1 != MAX_BLABLA)
fprintf(f, ",");
if (n%10 == 0)
fprintf(f, "\n\t");
}
fprintf(f, "};\n\n");
fprintf(f, "#endif // FOO_HEADER\n");
}
这将创建名单比利ONEAL谈到。
阶段3: 使用您刚刚在阶段2中创建的头文件,并在第一个项目中使用它来从新的getFooNumber()返回查找表中的值。
阶段4: 了解如何使用Qt,并了解可以直接嵌入文件并使用QFile(“:application/numberz.txt”)加载它。
备注: * C代码可能已损坏。我没有测试它。 *如果您使用的是Windows或Mac,则可以使用与资源系统类似的东西(MAC有类似的东西不可以?)
+1,创建一个小程序从数据生成C代码是非常唾手可得 – nos 2010-04-11 19:39:44
您可以只生成一个数组定义。例如,假设你有numbers.txt
:
$ head -5 numbers.txt
0.99043748698114
0.0243802034269436
0.887296518349228
0.0644020236531517
0.474582201929554
我一直在使用它生成的例子:
$ perl -E'say rand() for (1..250_000)' >numbers.txt
然后将其转换为C数组定义,你可以使用脚本:
$ perl -lpE'BEGIN{ say "double data[] = {"; };
> END{ say "};" };
> s/$/,/' > data.h < numbers.txt
它产生:
$ head -5 data.h
double data[] = {
0.99043748698114,
0.0243802034269436,
0.887296518349228,
0.0644020236531517,
$ tail -5 data.h
0.697015237317363,
0.642250552146166,
0.00577098769553785,
0.249176256744811,
};
它可以在你的程序中使用如下:
#include <stdio.h>
#include "data.h"
int main(void) {
// print first and last numbers
printf("%g %g\n", data[0], data[sizeof(data)/sizeof(*data)-1]);
return 0;
}
运行:
$ gcc *.c && ./a.out
0.990437 0.249176
++代码生成 – 2010-04-16 04:56:32
你在运行什么平台?如果您使用的是Windows,并且数字不会随时间变化,那么只需使用资源链接器将您的文本文件编程为资源,然后在您的代码中读取它。
您可以使用xxd
命令和-i
选项将任何文件转换为C
中的char向量。如果你在Windows上,你可以看看在Cygwin中使用它。
不是解决方案(这是之前给出的),但:不要把它放在头文件中。编写一个头文件,它定义了一个返回数组的函数。然后在.c文件中实现它。否则,你将最终在一个编译混乱...
只是在您的可执行程序,然后有另一个节的程序打开它的自己作为一个文件,获取字节,查找你已经编译并修改了它的字符串,但是你想直接使用它(确保把一个唯一的字符串放在那里,用二进制字符串来定位实际的区域),可能需要在执行另一个程序把数据写入原始程序并重新执行它,当原始程序重新执行时,它可以从以二进制形式声明的字符串中读取新的写入值,并使用该字符串执行任何任务。
什么平台?例如,你可以使用Win32资源吗? – 2010-04-11 18:39:44
类似的问题(无耻的插件):http://stackoverflow.com/questions/2481998/how-do-i-include-extremely-long-literals-in-c-source – 2010-04-11 18:47:15
对于所有那些建议使用数组,我也想到了这一点,但是因为编译时间过长而感到灰心。猜猜它毕竟是正确的。谢谢! – michael 2010-04-11 19:37:47