我需要找到一種方法在我的程序的可執行文件中存儲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