2010-03-20 3 views
5

J'ai un petit problème. Essentiellement, je dois stocker une grande liste d'entrées de la liste blanche dans mon programme, et je voudrais inclure une telle liste directement - je ne veux pas avoir à distribuer d'autres bibliothèques et autres, et je ne veux pas intégrer les chaînes dans une ressource Win32, pour un tas de raisons que je ne veux pas entrer dans le moment.Comment inclure des littéraux extrêmement longs dans une source C++?

J'ai simplement inclus mon grand whitelist dans mon dossier Cpp, et a été présenté avec cette erreur:

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

La chaîne elle-même est environ deux fois cette limite permise par VC++. Quelle est la meilleure façon d'inclure un tel littéral dans un programme?

EDIT:

Je stocker la chaîne comme ceci:

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 Il est utilisé lors de l'exécution d'une manière similaire à ceci:

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

Comment entreposez-vous la chaîne? Comme, est-il analysé et stocké dans un ensemble? – GManNickG

+0

@GMan: Voir question éditer –

+0

Y at-il une raison pour laquelle il doit être stocké exactement dans ce format? Il me semble que cela pourrait être mieux stocké dans une 'list <>' ou quelque chose comme ça. – greyfade

Répondre

8

Que diriez-vous d'un tableau? (Vous mettriez les virgules seulement après la limite légale pour chaque élément)

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|", 
... 
}; 

Vous pouvez utiliser l'instruction ci-dessous pour obtenir la chaîne combinée.

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

Si ce n'est que le double de la limite, la solution évidente semble être de re 2 (ou 3) de telles chaînes. :) Je suis sûr que votre code qui les lit au moment de l'exécution peut gérer cela assez facilement.

EDIT: Avez-vous besoin d'une regex pour une raison quelconque? Pourriez-vous diviser les grandes chaînes en une liste de jetons individuels et faire une simple comparaison de chaînes?

-1

problème Vous pourriez être démonté à (en Python):

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

une traduction directe de C++ serait:

// 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. C'est sympa pour Python, mais Python n'est pas ma langue cible Désolé ... 2. Cela semble être une copie de la réponse de Sameer ... –

+0

@Billy ONeal: 1. J'ai utilisé Python comme pseudo-code (comme une illustration succincte qui montre que vous n'avez pas besoin d'expressions rationnelles pour résoudre votre problème) 2. L'essence de la réponse est de supprimer regex et d'en utiliser une La réponse de Sameer est dans la racine de l'expression rationnelle – jfs

+0

Veuillez lire l'étiquette de question "C++" – Alrehamy

3

Supposons que vous avez réellement besoin de stocker une chaîne > 64 Ko de caractères (c.-à-d. Toutes les solutions ci-dessus «ne faites pas cela» ne s'appliquent pas.)

Pour faire MSV C heureux, au lieu de dire:

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

Vous pouvez convertir votre> 64k chaîne de caractères à des caractères individuels représentés comme des entiers:

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

où chaque lettre a été convertie en son équivalent ascii (97 == 'a', etc.), et un terminateur NUL a été ajouté à la fin.

MSVC2010 est au moins satisfait de cela.

+0

ou const wchar_t foo [] dans ce cas. – rxantos

Questions connexes