PDA

View Full Version : [C++] Incorporare file di testo dentro eseguibile


ka0s
14-11-2005, 11:35
E' possibile compilare un programma in modo che incorpori al suo interno un determinato file (di testo) e fare in modo che durante l'esecuzione del programma lo utilizzi (ad es. per creare altri file che contengano il contenuto del file originale)?

Sarebbe comodo se uno volesse distribuire un programma senza allegarci altri file... quindi distribuendo solo l'exe...

kk3z
14-11-2005, 12:03
Dovrebbe essere possibile includere qualsiasi tipo di file in un exe attraverso il file .rc con questa sintassi:

#define id 10
#define nome_risorsa 50

id nome_risorsa "path_relativa_della_risorsa"
come per esempio

ID_HTML HTML "pagina.html"

e poi puoi accederci tramite il protocollo res:
res://path_all'eseguibile/ID_HMTL
come per esempio

res://c:\\qualcosa.exe/ID_HMTL

dovrebbe essere possibile quindi qualcosa del genere
FILE *fp;
fp = fopen("res://c:\\qualcosa.exe/ID_FILEDITESTO", "r");

chiaramente non credo tu ci possa scrivere dentro..

ka0s
14-11-2005, 18:00
mettiamo che io voglia incorporare un file di testo e poi nel programma devo solo copiare il contenuto di questo file dentro un altro che verrà creato dal programma stesso... è possibile farlo?

per quanto riguarda il codice che hai postato non ho capito molto...

andbin
16-11-2005, 10:18
mettiamo che io voglia incorporare un file di testo e poi nel programma devo solo copiare il contenuto di questo file dentro un altro che verrà creato dal programma stesso... è possibile farlo?

per quanto riguarda il codice che hai postato non ho capito molto...
Hai parlato di C++ e di exe, quindi suppongo che tu stia sviluppando una applicazione in Windows con questo linguaggio.
Una possibilità (non è l'unica comunque) per fare quello che chiedi potrebbe essere la seguente. Supponi di avere un file di testo con alcune righe del tipo:

Prova1
Prova2
Prova3

Se tu avessi un sorgente C/C++ del tipo:

char miotesto[] =
"Prova1
Prova2
Prova3";

potresti usare la variabile miotesto come vuoi, per leggere, scrivere su file il testo, ecc...
A questo punto puoi farti una piccola utility, anche a linea di comando, che dato un file di testo, ti crea un file C/C++ come sopra, poi includi il sorgente nel tuo progetto e usi la variabile come vuoi.

Occhio solo ai caratteri, ad esempio se incontri un doppio apice " devi convertirlo in \" nel sorgente C/C++ generato.

ka0s
16-11-2005, 11:00
Ah ho capito cosa vuoi dire... però il file di testo che dovrei includere contiene una marea di caratteri tipo " ecc. che quindi andrebbero tutti "sistemati"... è un lavoraccio (tra l'altro abbastanza inutile credo...).

Se fosse possibile includerlo all'interno come detto da kk3z in modo da leggere e copiare in un altro file sarebbe molto piu veloce e comodo... ora cmq che ho un po' di tempo proverò i vari procedimenti, se avete altre proposte e soluzioni fatemele sapere! ;)

andbin
16-11-2005, 13:47
Ah ho capito cosa vuoi dire... però il file di testo che dovrei includere contiene una marea di caratteri tipo " ecc. che quindi andrebbero tutti "sistemati"... è un lavoraccio (tra l'altro abbastanza inutile credo...).

Se fosse possibile includerlo all'interno come detto da kk3z in modo da leggere e copiare in un altro file sarebbe molto piu veloce e comodo... ora cmq che ho un po' di tempo proverò i vari procedimenti, se avete altre proposte e soluzioni fatemele sapere! ;)
Beh, no ... dai! Un lavoraccio proprio no! Se vuoi ti posto un esempio semplice e minimale per fare una utility, come ti ho spiegato già prima, per convertire un file di testo in un sorgente C/C++:

#include <stdio.h>

int main (int argc, char *argv[])
{
FILE *fi, *fo;
int ch;
long size = 0;

if (argc == 4)
{
if ((fi = fopen (argv[1], "r")) != NULL)
{
if ((fo = fopen (argv[2], "w")) != NULL)
{
fprintf (fo, "char %s[] =\n\"", argv[3]);

while ((ch = getc (fi)) != EOF)
{
if (ch == '"' || ch == '\\')
putc ('\\', fo);

putc (ch, fo);
size++;
}

fprintf (fo, "\";\n");
fprintf (fo, "long %s_size = %ld;", argv[3], size);
fclose (fo);
}

fclose (fi);
}
}

return 0;
}
Lo compili e poi lo usi con 3 parametri:

nome-utility prova.txt prova.c miotesto
Chiaramente dai il nome tu alla utility come vuoi!
Io l'ho già provato, funziona benissimo e con qualunque carattere.
E, nota, ti crea pure una variabile "long" con la lunghezza del testo.
Poi vedi tu. Ciao.

ka0s
16-11-2005, 16:37
Wow!! veramente notevole!! grazie mille!!! Adesso proverò ad includerlo in un progetto e vedere come mi funziona ;)

PS: non è che mi spieghersti (sempre se ti va ed hai tempo chiaramente) abbastanza dettagliatamente il sorgente che mi hai postato? Dato che non riesco a capirlo nella sua interezza... mi faresti un favore almeno so con cosa lavoro ;)

PPS: ehm scusa la domanda banale: nel mio file sorgente devo mettere #include <nomefile.c> (che ho creato con il prog. che hai postato tu) e poi come faccio a richiamare il char miotesto[]=".." ??

kk3z
16-11-2005, 17:28
mettiamo che io voglia incorporare un file di testo e poi nel programma devo solo copiare il contenuto di questo file dentro un altro che verrà creato dal programma stesso... è possibile farlo?

per quanto riguarda il codice che hai postato non ho capito molto...

Usi un ide? Che compilatore usi? Hai familiarità con i progetti?

andbin
16-11-2005, 19:54
PS: non è che mi spieghersti (sempre se ti va ed hai tempo chiaramente) abbastanza dettagliatamente il sorgente che mi hai postato? Dato che non riesco a capirlo nella sua interezza... mi faresti un favore almeno so con cosa lavoro ;)
Certo che posso spiegartelo. Il programma accetta 3 parametri, il nome del file di testo in input, il nome del file sorgente da generare e il nome della variabile da usare. Potendo specificare anche il nome della variabile, l'ho reso più generico, nel caso uno volesse avere più blocchi di testo in una applicazione (dovendo quindi usare nomi diversi).
Il programma controlla prima il numero di parametri, poi apre con la fopen i due file (uno in lettura e l'altro in scrittura naturalmente).
Dopodiché scrive la dichiarazione della variabile e inizia il ciclo di lettura carattere per carattere. Non è sicuramente ottimizzato ma come esempio va bene.
Nel ciclo, viene letto un carattere per volta con la getc dal file di testo fino a quando si raggiunge l'end of file (EOF).
Ogni carattere viene scritto in output pari pari, con l'unico fatto che il doppio apice e il backslash vengono preceduti da un backslash che funge da "escape".
Il ciclo poi si chiude e viene scritta la fine della dichiarazione più una nuova dichiarazione con la lunghezza del testo (l'ho messa perché può sempre tornare utile).
Alla fine vengono chiusi gli stream dei file.
Se c'è qualcosa di più specifico del sorgente che non ti è chiaro chiedi pure, non c'è problema.
Naturalmente il programma si può migliorare (inserendo la gestione degli errori) e anche ottimizzare dal punto di vista delle prestazioni.

PPS: ehm scusa la domanda banale: nel mio file sorgente devo mettere #include <nomefile.c> (che ho creato con il prog. che hai postato tu) e poi come faccio a richiamare il char miotesto[]=".." ??
Beh, se il sorgente generato lo usi solo in un altro sorgente, puoi certamente usare la direttiva include. Usa solo l'estensione .h. In genere non è bello mettere #include "file.c".
La soluzione più pulita ed elegante comunque è quella di compilare il sorgente generato (in modo da ottenere un file oggetto da linkare insieme al resto della tua applicazione) e mettere, nel sorgente dove ti serve la variabile, un "extern char miotesto[];"

ka0s
16-11-2005, 20:40
Grazie per la spiegazione :D

Per quanto riguarda il resto... mi sento un po' stupido :P non riesco a fargli usare il char miotesto come vorrei... se uso #include <nomefile.h> non me lo trova... il compilatore mi dice: "No such file or directory" eppure c'è... :eek:
Dato che cmq l'altro procedimento che mi hai indicato lo ritieni migliore ho provato anche quello... ma come faccio a compilarlo come file oggetto? (uso dev-cpp). E inoltre, una volta ottenuto questo file, come faccio a linkarlo insieme al resto del programma? Scusa le domande banali ma queste cose proprio non le so... nel frattempo cmq ci provo da solo ;)

andbin
16-11-2005, 21:20
Grazie per la spiegazione :D

Per quanto riguarda il resto... mi sento un po' stupido :P non riesco a fargli usare il char miotesto come vorrei... se uso #include <nomefile.h> non me lo trova... il compilatore mi dice: "No such file or directory" eppure c'è... :eek:
Esistono due modi per specificare un file di include:

#include <file.h>
oppure
#include "file.h"

La differenza è che nel primo caso il compilatore cerca il file nei path specificati nella configurazione dell'ambiente di sviluppo (tipicamente include di sistema e include di librerie di terze parti) mentre nel secondo caso il file viene cercato a partire dal path dove risiede il sorgente che si sta compilando.

Dato che cmq l'altro procedimento che mi hai indicato lo ritieni migliore ho provato anche quello... ma come faccio a compilarlo come file oggetto? (uso dev-cpp). E inoltre, una volta ottenuto questo file, come faccio a linkarlo insieme al resto del programma? Scusa le domande banali ma queste cose proprio non le so... nel frattempo cmq ci provo da solo ;)
Il dev-cpp lo conosco solo di nome ... non l'ho mai usato. :(
Con il gcc è semplice. Esempio:

Compilazione:
gcc -c -o file1.o file1.c
gcc -c -o file2.o file2.c
ecc...

Link:
gcc -o eseguibile file1.o file2.o ecc....

ka0s
16-11-2005, 22:10
Esistono due modi per specificare un file di include:

#include <file.h>
oppure
#include "file.h"

La differenza è che nel primo caso il compilatore cerca il file nei path specificati nella configurazione dell'ambiente di sviluppo (tipicamente include di sistema e include di librerie di terze parti) mentre nel secondo caso il file viene cercato a partire dal path dove risiede il sorgente che si sta compilando.
Ah già lo sapevo pure... :doh:


Con il gcc è semplice. Esempio:

Compilazione:
gcc -c -o file1.o file1.c
gcc -c -o file2.o file2.c
ecc...

Link:
gcc -o eseguibile file1.o file2.o ecc....
grazie mille! ;)