2010-04-11 76 views
7

我需要找到一種方法在我的程序的可執行文件中存儲250 KB的純文本數字。如何將數據存儲在可執行文件中

通常,我會把數據放在一個單獨的文件中,讓程序在運行時讀取它,但這不是一個選項。相反,程序和數據需要在一個可執行文件中。

我絕對不知道該怎麼做(除了寫250.000 #defines :-),我會很感激任何建議。

+2

什麼平臺?例如,你可以使用Win32資源嗎? – 2010-04-11 18:39:44

+1

類似的問題(無恥的插件):http://stackoverflow.com/questions/2481998/how-do-i-include-extremely-long-literals-in-c-source – 2010-04-11 18:47:15

+1

對於所有那些建議使用數組,我也想到了這一點,但是因爲編譯時間過長而感到灰心。猜猜它畢竟是正確的。謝謝! – michael 2010-04-11 19:37:47

回答

9

如何處理某種數組。只要把這個定義在文件中並編譯成你的程序:

int external_data[] = 
{ 
    ... 
}; 

可以讓編譯器告訴你有多少元素在外部數據:

size_t external_data_max_idx = sizeof(external_data)/sizeof(*external_data); 
+2

+1使用空括號語法。 – 2010-04-11 18:46:04

+0

+1用於在*獨立*文件中建議定義。我目前正在使用這種技術,我只需要更改文件並重建,特別是當數據發生變化時。 – 2010-04-12 17:26:40

4

存儲它作爲一個常量數組:

/* 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中。

+3

您可以使用'data []'而不是使用一些數字宏。 – 2010-04-11 18:45:17

0

這聽起來像你想避免把它在源文件中,但是這確實是我會怎麼做:

int numbers[250000] = {1, 2, ...}; 

這在技術上是可以將它們保存爲純文本文件,並編寫創建一個新的d一個連接指令文件在一個合適的尺寸部分,並結合他們,但真的沒有理由。把這個定義在一個單獨的文件和#包括它變成了需要

+1

請注意,你可以讓「數字[]'和編譯器會爲你計算。 – 2010-04-11 18:42:49

+0

是的,但是如果我知道我想包括它的數組中有多少東西,那麼看着它的人​​都知道立即的大小,所以如果我搞砸了,忘記/重複一個我會得到一個編譯時錯誤 – 2010-04-11 19:44:54

0

你可以適應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" 
}; 
1

我與以前的答案一致。最好的方法是將其存儲在代碼中,然後將其編譯到程序中。 爲了參數的緣故,您可以查看可執行文件的格式並在其中添加一些數據/代碼(這是大量病毒的工作原理),並從可執行文件中讀取數據並獲取數據。 http://refspecs.freestandards.org/elf/elf.pdf具有可執行文件的格式。 這再次是爲了爭論,不建議。

2

讓我們假設數字是常數。讓我們假設,你可以在「預編譯」階段計算一次這個列表。讓我們假設有一個函數可以「返回」該列表。

第一階段: 編寫調用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有類似的東西不可以?)

+0

+1,創建一個小程序從數據生成C代碼是非常唾手可得 – nos 2010-04-11 19:39:44

5

您可以只生成一個數組定義。例如,假設你有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 
+0

++代碼生成 – 2010-04-16 04:56:32

0

你在運行什麼平臺?如果您使用的是Windows,並且數字不會隨時間變化,那麼只需使用資源鏈接器將您的文本文件編程爲資源,然後在您的代碼中讀取它。

3

您可以使用xxd命令和-i選項將任何文件轉換爲C中的char向量。如果你在Windows上,你可以看看在Cygwin中使用它。

0

不是解決方案(這是之前給出的),但:不要把它放在頭文件中。編寫一個頭文件,它定義了一個返回數組的函數。然後在.c文件中實現它。否則,你將最終在一個編譯混亂...

0

只是在您的可執行程序,然後有另一個節的程序打開它的自己作爲一個文件,獲取字節,查找你已經編譯並修改了它的字符串,但是你想直接使用它(確保把一個唯一的字符串放在那裏,用二進制字符串來定位實際的區域),可能需要在執行另一個程序把數據寫入原始程序並重新執行它,當原始程序重新執行時,它可以從以二進制形式聲明的字符串中讀取新的寫入值,並使用該字符串執行任何任務。

相關問題