2010-03-20 9 views
5

Ho un po 'di problemi. Essenzialmente, ho bisogno di memorizzare una grande lista di voci autorizzate all'interno del mio programma, e mi piacerebbe includere direttamente un elenco di questo tipo - Non voglio dover distribuire altre librerie e simili, e non voglio incorporare le stringhe in una risorsa Win32, per un sacco di motivi per cui non voglio entrare in questo momento.Come posso includere letterali estremamente lunghi in sorgente C++?

ho inserito semplicemente il mio grande lista bianca nel mio file cpp, ed è stato presentato con questo errore:

1>ServicesWhitelist.cpp(2807): fatal error C1091: compiler limit: string exceeds 65535 bytes in length 

la stringa stessa è circa il doppio di questo limite consentito dalla VC++. Qual è il modo migliore per includere un così grande letterale in un programma?

EDIT:

sto memorizzare la stringa in questo modo:

const std::wstring servicesWhitelist 
(
L".NETFRAMEWORK|" 
L"_IOMEGA_ACTIVE_DISK_SERVICE_|" 
L"{6080A529-897E-4629-A488-ABA0C29B635E}|" 
L"{834170A7-AF3B-4D34-A757-E05EB29EE96D}|" 
L"{85CCB53B-23D8-4E73-B1B7-9DDB71827D9B}|" 
L"{95808DC4-FA4A-4C74-92FE-5B863F82066B}|" 
L"{A7447300-8075-4B0D-83F1-3D75C8EBC623}|" 
L"{D31A0762-0CEB-444E-ACFF-B049A1F6FE91}|" 
L"{E2B953A6-195A-44F9-9BA3-3D5F4E32BB55}|" 
L"{EDA5F5D3-9E0F-4F4D-8A13-1D1CF469C9CC}|" 
L"2WIREPCP|" 
//About 3800 more lines 
); 

EDIT2 E 'utilizzato in fase di esecuzione in un modo simile a questo:

static const boost::wregex servicesWhitelistRegex(servicesWhitelist); 
std::wstring service; 
//code to populate service 
if (!boost::regex_match(service, servicesWhitelistRegex)) 
//Do something to print service 
+0

Come stai Memorizzazione della stringa? Come, è analizzato e memorizzato in un set? – GManNickG

+0

@GMan: Vedi domanda modifica –

+0

C'è qualche ragione per cui deve essere memorizzato esattamente in questo formato? Mi sembra che potrebbe essere meglio memorizzato in un 'elenco <>' o qualcosa del genere. – greyfade

risposta

8

Che ne dici di un array? (Si dovrebbe mettere le virgole solo dopo che il limite legale per ogni elemento)

const std::wstring servicesWhitelist[] = { 
L".NETFRAMEWORK|", 
L"_IOMEGA_ACTIVE_DISK_SERVICE_|", 
L"{6080A529-897E-4629-A488-ABA0C29B635E}|", 
L"{834170A7-AF3B-4D34-A757-E05EB29EE96D}|", 
L"{85CCB53B-23D8-4E73-B1B7-9DDB71827D9B}|", 
L"{95808DC4-FA4A-4C74-92FE-5B863F82066B}|", 
L"{A7447300-8075-4B0D-83F1-3D75C8EBC623}|", 
L"{D31A0762-0CEB-444E-ACFF-B049A1F6FE91}|", 
L"{E2B953A6-195A-44F9-9BA3-3D5F4E32BB55}|", 
L"{EDA5F5D3-9E0F-4F4D-8A13-1D1CF469C9CC}|", 
L"2WIREPCP|", 
... 
}; 

è possibile utilizzare l'istruzione qui sotto per ottenere la stringa combinato.

accumulate(servicesWhitelist, servicesWhitelist+sizeof(servicesWhitelist)/sizeof(servicesWhitelist[0]), "") 
2

Se è solo circa il doppio del limite, la soluzione ovvia sembrerebbe essere il problema re 2 (o 3) tali stringhe. :) Sono sicuro che il tuo codice che li legge in runtime può gestirlo con sufficiente facilità.

MODIFICA: È necessario utilizzare un'espressione regolare per qualche motivo? Potresti suddividere le stringhe grandi in un elenco di token individuali e fare un semplice confronto tra stringhe?

-1

problema che potrebbe essere messo a nudo giù a (in Python):

whitelist_services = { ".NETFRAMEWORK", "_IOMEGA_ACTIVE_DISK_SERVICE_" } 
if service in whitelist_services: 
    print service, "is a whitelisted service" 

una traduzione diretta a C++ potrebbe essere:

// g++ *.cc -std=c++0x && ./a.out 
#include <iostream> 
#include <unordered_set> 

namespace { 
    typedef const wchar_t* str_t; 
    // or 
    ////typedef std::wstring str_t; 
    str_t servicesWhitelist[] = { 
    L".NETFRAMEWORK", 
    L"_IOMEGA_ACTIVE_DISK_SERVICE_", 
    }; 
    const size_t N = sizeof(servicesWhitelist)/sizeof(*servicesWhitelist); 

    // if you need to search for multiple services then a hash table 
    // could speed searches up O(1). Otherwise std::find() on the array 
    // might be sufficient O(N), or std::binary_search() on sorted array 
    // O(log N) 
    const std::unordered_set<str_t> services 
    (servicesWhitelist, servicesWhitelist + N); 
} 

int main() { 
    str_t service = L".NETFRAMEWORK"; 
    if (services.find(service) != services.end()) 
    std::wcout << service << " is a whitelisted service" << std::endl; 
} 
+0

1. Questo è bello per Python, ma Python non è la mia lingua di destinazione, mi dispiace 2. Questa sembra essere una copia della risposta di Sameer ... –

+0

@Billy ONeal: 1. Ho usato Python come pseudo-codice (come un'illustrazione succinta che mostra che non è necessario regex per risolvere il problema) 2. L'essenza della risposta è di rilasciare espressioni regolari e usarne una degli approcci mostrati La risposta di Sameer è nella radice della regex – jfs

+0

per favore leggi la domanda "C++" – Alrehamy

3

Supponiamo che effettivamente bisogno di memorizzare una stringa > 64k caratteri (vale a dire tutte le soluzioni "solo non farlo" sopra non si applicano.)

Per rendere MSV C felice, invece di dire:

const char *foo = "abcd..."; 

È possibile convertire il vostro> 64k stringa di caratteri da singoli caratteri rappresentati come numeri interi:

const char foo[] = { 97, 98, 99, 100, ..., 0 }; 

Dove ogni lettera è stato convertito al suo ascii equivalente (97 == 'a', ecc.) e alla fine è stato aggiunto un terminatore NUL.

MSVC2010 è soddisfatto di questo.

+0

o const wchar_t foo [] in questo caso. – rxantos