Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Caricare dati con etichetta - opinioni? consigli?
Forum - C/C++ - Caricare dati con etichetta - opinioni? consigli?

Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 14:36
Venerdì, 03/04/2020
Per avere rapidamente a disposizione un sistema per caricare file di impostazioni formattati testualmente (e quindi modificabili "a mano") per i miei programmini in C, ho messo insieme un meccanismo che usa tag etichettati in una forma simile a queste:

etichetta(dato) altra_etichetta(altro dato)

etichetta<|dato|> altra_etichetta<|altro dato|>

etichetta123dato456 altra_etichetta123altro dato456

... e così via.

In tutti e tre gli esempi i due dati sono "dato" e "altro dato".
In tutti e tre gli esempi il dato è "accompagnato" da un clausola di apertura e una di chiusura. La clausola di apertura è immediatamente preceduta da un'etichetta univoca, diciamo un ID, a sua volta preceduta da un carattere di spaziatura (a meno che sia subito "in testa" al file, nel qual caso può essere omesso).
L'etichetta e le clausole di apertura/chiusura possono essere qualsiasi stringa venga in mente (caratteri da 1 byte), purché si stia attenti a non generare ambiguità.
Il riconoscimento di etichette e clausole di apertura/chiusura distingue tra maiuscole e minuscole.

Il meccanismo è altamente inefficiente, e si presta solo all'uso con quantità di dati ridotte. In queste condizioni penso possa essere pratico per via della sua immediatezza.

Ecco il codice, per i curiosi.
I file tag_etichettati.h e tag_etichettati.c sono conformati in modo da poter essere compilati come libreria statica.
Il file main.c contiene un programmino che ho predisposto per testare le funzioni di lettura dei dati.

File tag_etichettati.h
Codice sorgente - presumibilmente C++

  1. /* =============================================================================
  2.      LIBRERIA TAG ETICHETTATI
  3.      v 1.0.0, aprile 2020
  4. ============================================================================= */
  5.  
  6. #ifndef TAG_ETICHETTATI_H_INCLUDED
  7. #define TAG_ETICHETTATI_H_INCLUDED
  8.  
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17.  
  18. enum {
  19.     kTEErr_NoErr,           // tutto bene!
  20.     kTEErr_PtrNULL,         // puntatore NULL
  21.     kTEErr_NoAlloc,         // allocazione di memoria fallita
  22.     kTEErr_NomeFileVuoto,   // il nome del file e' una stringa vuota
  23.     kTEErr_NoFile,          // il file non e' stato aperto
  24.     kTEErr_NoLettura,       // non e' stato possibile leggere dal file
  25.     kTEErr_FileEnorme,      // le dimensioni del file superano i 4GB
  26.     kTEErr_StrVuota,        // stringa vuota
  27.     kTEErr_NoFormato,       // formato non valido
  28.     kTEErr_NoEtich,         // etichetta tag non trovata
  29.     kTEErr_NoCont,          // non e' stato trovato alcun contenuto compreso
  30.                             // tra i delimitatori di apertura e di chiusura
  31.     kTEErr_NoInt,           // il contenuto del tag non e' un valore intero
  32.     kTEErr_NoFloat,         // il contenuto del tag non e' un valore con virgola
  33.     kTEErr_TotErrori        // la quantita' totale dei codici d'errore enumerati
  34. };
  35.  
  36. /*==============================================================================
  37. Carica il contenuto del file individuato tramite i dati passati in nomeFile.
  38. I dati vengono caricati in un'area di memoria allocata dinamicamente tramite
  39. malloc() l'indirizzo della quale viene inserito in *contFile. In coda ai dati
  40. caricati viene inserito un terminatore '\0'. Le dimensioni dei dati caricati
  41. (escluso il terminatore) vengono inserite in *lContFile, se il parametro passato
  42. non e' NULL.
  43.  
  44. Spetta al chiamante liberare la memoria eventualmente allocata. In caso di
  45. errori non viene allocata alcuna memoria e il contenuto di contFile e' NULL.
  46.  
  47. PARAMETRI
  48.     contFile    (out) in *contFile viene inserito l'indirizzo dell'area di
  49.                 memoria dinamica allocata per copiarci i dati caricati
  50.     lContFile   (out) in *lContFile viene inserito un valore che rappresenta le
  51.                 dimensioni dei dati caricati, escluso il terminatore aggiunto
  52.                 dalla funzione
  53.     nomeFile    (in) gli estremi del file dal quale vengono caricati i dati
  54.  
  55. VALORE DI RITORNO
  56.     Un codice di errore. In caso di errore, non viene allocata alcuna memoria e
  57.     il contenuto di contFile e' NULL.
  58. ==============================================================================*/
  59.  
  60. int TE_carica_file( char **contFile, size_t *lContFile, const char *nomeFile );
  61.  
  62. /*==============================================================================
  63. Individua nella stringa passata tramite il secondo parametro il tag con
  64. l'etichetta specificata, il cui contenuto e' compreso tra i delimitatori
  65. indicati. Il contenuto del tag trovato viene copiato in un'area di memoria
  66. allocata dinamicamente per mezzo di malloc() e l'indirizzo dell'area di memoria
  67. allocata viene restituito inserendolo nell'indirizzo specificato dal chiamante
  68. tramite il primo parametro.
  69.  
  70. Spetta al chiamante liberare la memoria eventualmente allocata. In caso di
  71. errori non viene allocata alcuna memoria e il contenuto di pEstratto e' NULL.
  72.  
  73. PARAMETRI
  74.     pEstratto       (out) a questo indirizzo viene inserito l'indirizzo della
  75.                     memoria allocata tramite malloc() nella quel è stato copiato
  76.                     il contenuto del tag eventualmente trovato;
  77.                     se si verificano errori, non viene inserito nulla
  78.     lEstratto       (out) a questo indirizzo viene inserito un valore che
  79.                     rappresenta la lunghezza della stringa del tag (terminatore
  80.                     escluso);
  81.                     se questo parametro e' NULL, la lunghezza non viene
  82.                     comunicata al chiamante
  83.     stringaDati     (in) la stringa nella quale viene cercato il tag
  84.     etichettaTag    (in) una stringa che rappresenta il nome dell'etichetta del
  85.                     tag da estrarre
  86.     tagApertura     (in) una stringa che rappresenta la sequenza di caratteri
  87.                     che costituisce il delimitatore di apertura del contenuto
  88.                     del tag
  89.     tagChiusura     (in) una stringa che rappresenta la sequenza di caratteri
  90.                     che costituisce il delimitatore di chiusura del contenuto
  91.                     del tag
  92.  
  93. VALORE DI RITORNO
  94.     Un codice di errore. In caso di errore, non viene allocata alcuna memoria e
  95.     il contenuto di pEstratto e' NULL.
  96. ==============================================================================*/
  97.  
  98. int TE_estrai_tag_stringa( char **pEstratto, size_t *lEstratto,
  99.     const char *stringaDati, const char *etichettaTag,
  100.     const char *tagApertura, const char *tagChiusura );
  101.  
  102. /*==============================================================================
  103. Le tre funzioni che seguono individuano nella stringa passata tramite il secondo
  104. parametro il tag con l'etichetta specificata, il cui contenuto e' compreso tra i
  105. delimitatori indicati. Il contenuto del tag trovato viene convertito nel tipo di
  106. dato specifico di ogni singola funzione e restituito inserendolo nell'indirizzo
  107. specificato dal chiamante tramite il primo parametro.
  108.  
  109. PARAMETRI
  110.     pEstratto       (out) a questo indirizzo viene inserito il valore letto;
  111.                     se si verificano errori, non viene inserito nulla
  112.     stringaDati     (in) la stringa nella quale viene cercato il tag
  113.     etichettaTag    una stringa che rappresenta il nome dell'etichetta del tag
  114.                     da estrarre
  115.     tagApertura     (in) una stringa che rappresenta la sequenza di caratteri
  116.                     che costituisce il delimitatore di apertura del contenuto
  117.                     del tag
  118.     tagChiusura     (in) una stringa che rappresenta la sequenza di caratteri
  119.                     che costituisce il delimitatore di chiusura del contenuto
  120.                     del tag
  121.  
  122. VALORE DI RITORNO
  123.     Un codice di errore. In caso di errore, il contenuto di pEstratto non viene
  124.     modificato.
  125. ==============================================================================*/
  126.  
  127. int TE_estrai_tag_intero( long long *pEstratto,
  128.     const char *stringaDati, const char *etichettaTag,
  129.     const char *tagApertura, const char *tagChiusura );
  130.  
  131. int TE_estrai_tag_virgola( long double *pEstratto,
  132.     const char *stringaDati, const char *etichettaTag,
  133.     const char *tagApertura, const char *tagChiusura );
  134.  
  135. int TE_estrai_tag_esadecimale( long long *pEstratto,
  136.     const char *stringaDati, const char *etichettaTag,
  137.     const char *tagApertura, const char *tagChiusura );
  138.  
  139. /*==============================================================================
  140. Restituisce il puntatore a una stringa che descrive brevemente il tipo di errore
  141. corrispondente al codice passato come parametro.
  142. NON BISOGNA DEALLOCARE IL PUNTATORE RESTITUITO (punta a una costante stringa).
  143. ==============================================================================*/
  144.  
  145. const char *TE_descrizione_errore( int codice );
  146.  
  147. #ifdef __cplusplus
  148. }
  149. #endif
  150.  
  151. #endif // TAG_ETICHETTATI_H_INCLUDED



File tag_etichettati.c
Codice sorgente - presumibilmente Delphi

  1. /* =============================================================================
  2.      LIBRERIA TAG ETICHETTATI
  3.      v 1.0.0, aprile 2020
  4. ============================================================================= */
  5.  
  6. #include "tag_etichettati.h"
  7.  
  8. static const char *TE_ErrStr[kTEErr_TotErrori] = {
  9.     "ok",
  10.     "puntatore NULL",
  11.     "allocazione di memoria fallita",
  12.     "nome del file vuoto",
  13.     "impossibile aprire il file",
  14.     "impossibile leggere dal file",
  15.     "le dimensioni del file superano i 4GB",
  16.     "stringa vuota",
  17.     "formato non valido",
  18.     "etichetta non valida",
  19.     "contenuto non trovato",
  20.     "valore non intero",
  21.     "valore non in virgola mobile"
  22. };
  23.  
  24. static int TE_trova_contenuto( const char **cont, size_t *lCont,
  25.                                const char *s,
  26.                                const char *a, size_t la,
  27.                                const char *c, size_t lc );
  28.  
  29. int TE_carica_file( char **contFile, size_t *lContFile, const char *nomeFile ) {
  30.     int err = kTEErr_NoErr;
  31.  
  32.     if( contFile ) *contFile = NULL;
  33.  
  34.     if( contFile && nomeFile ) {
  35.         if( *nomeFile ) {
  36.  
  37.             FILE *f = fopen( nomeFile, "r" );
  38.  
  39.             if( f ) {
  40.                 size_t i, dimFile = 0;
  41.                 int c = fgetc(f);
  42.  
  43.                 while( EOF!=c && dimFile!=((size_t)-1) )
  44.                     { c = fgetc(f); ++dimFile; }
  45.  
  46.                 if( dimFile != ((size_t)-1) ) {
  47.                     char *cfTmp = malloc( dimFile+1 );
  48.  
  49.                     if( NULL != cfTmp ) {
  50.                         for( rewind(f), i=0, c=fgetc(f); EOF!=c; ++i ) {
  51.                             cfTmp[i] = c;
  52.                             c = fgetc(f);
  53.                         }
  54.  
  55.                         if( i==dimFile ) {
  56.                             cfTmp[dimFile] = '\0';
  57.                             *contFile = cfTmp;
  58.                             if( NULL != lContFile )
  59.                                 *lContFile = dimFile;
  60.                             err = kTEErr_NoErr;
  61.                         }
  62.                         else {
  63.                             free( cfTmp );
  64.                             err = kTEErr_NoLettura;
  65.                         }
  66.                     } else err = kTEErr_NoAlloc;
  67.                 } else err = kTEErr_FileEnorme;
  68.  
  69.                 fclose( f );
  70.             } else err = kTEErr_NoFile;
  71.         } else err = kTEErr_NomeFileVuoto;
  72.     } else err = kTEErr_PtrNULL;
  73.  
  74.     return err;
  75. }
  76.  
  77. int TE_estrai_tag_stringa( char **pEstratto, size_t *lEstratto,
  78.     const char *stringaDati, const char *etichettaTag,
  79.     const char *tagApertura, const char *tagChiusura ) {
  80.     int err = kTEErr_NoErr;
  81.  
  82.     if( pEstratto ) *pEstratto = NULL;
  83.  
  84.     if( pEstratto && stringaDati && etichettaTag && tagApertura && tagChiusura ) {
  85.         size_t ls = strlen( stringaDati );
  86.         size_t le = strlen( etichettaTag );
  87.         size_t la = strlen( tagApertura );
  88.         size_t lc = strlen( tagChiusura );
  89.  
  90.         if( ls && le && la && lc ) {
  91.             const char *p = stringaDati;
  92.             const char *cont;
  93.             size_t lCont;
  94.  
  95.             do {
  96.                 err = TE_trova_contenuto( &cont, &lCont, p, tagApertura, la, tagChiusura, lc );
  97.  
  98.                 if( kTEErr_NoErr == err ) {
  99.                     // la corrispondenza dell'etichetta viene accettata come
  100.                     // valida solo se e' la prima etichetta della stringa dei
  101.                     // dati o se e' immediatamente preceduta da un carattere di
  102.                     // spaziatura riconosciuto come tale da isspace()
  103.                     const char *pe = cont-la-le; // pe: puntatore etichetta
  104.                     int primo = (stringaDati==pe);
  105.  
  106.                     if( (primo||((!primo)&&isspace(*(pe-1)))) &&
  107.                         0==strncmp(pe,etichettaTag,le) ) {
  108.                         char *eTmp = malloc( lCont+1 );
  109.  
  110.                         if( NULL != eTmp ) {
  111.                             memcpy( eTmp, cont, lCont );
  112.                             eTmp[lCont] = '\0';
  113.                             *pEstratto = eTmp;
  114.                             if( NULL!=lEstratto )
  115.                                 *lEstratto = lCont;
  116.                             return kTEErr_NoErr;
  117.                         } else return kTEErr_NoAlloc;
  118.                     }
  119.  
  120.                     // se arriva qui, ripete il ciclo per
  121.                     // controllare il prossimo contenuto
  122.                     p = cont+lCont+lc;
  123.  
  124.                 } else return err;
  125.             } while( *p && p-stringaDati<ls );
  126.             err = kTEErr_NoEtich;
  127.         } else err = kTEErr_StrVuota;
  128.     } else err = kTEErr_PtrNULL;
  129.  
  130.     return err;
  131. }
  132.  
  133. int TE_estrai_tag_intero(   long long *pEstratto,
  134.     const char *stringaDati, const char *etichettaTag,
  135.     const char *tagApertura, const char *tagChiusura ) {
  136.     char *s = NULL;
  137.  
  138.     int err = TE_estrai_tag_stringa( &s, NULL, stringaDati,
  139.                                      etichettaTag, tagApertura, tagChiusura );
  140.  
  141.     if( kTEErr_NoErr == err ) {
  142.         char *fine;
  143.         long long eTmp = strtoll( s, &fine, 10 );
  144.  
  145.         if( s!=fine && '\0'==*fine )
  146.             *pEstratto = eTmp;
  147.         else err = kTEErr_NoInt;
  148.  
  149.         free( s );
  150.     }
  151.  
  152.     return err;
  153. }
  154.  
  155. int TE_estrai_tag_virgola( long double *pEstratto,
  156.     const char *stringaDati, const char *etichettaTag,
  157.     const char *tagApertura, const char *tagChiusura ) {
  158.     char *s = NULL;
  159.  
  160.     int err = TE_estrai_tag_stringa( &s, NULL, stringaDati,
  161.                                      etichettaTag, tagApertura, tagChiusura );
  162.  
  163.     if( kTEErr_NoErr == err ) {
  164.         char *fine;
  165.         long double eTmp = strtold( s, &fine );
  166.  
  167.         if( s!=fine && '\0'==*fine )
  168.             *pEstratto = eTmp;
  169.         else err = kTEErr_NoFloat;
  170.  
  171.         free( s );
  172.     }
  173.  
  174.     return err;
  175. }
  176.  
  177. int TE_estrai_tag_esadecimale(   long long *pEstratto,
  178.     const char *stringaDati, const char *etichettaTag,
  179.     const char *tagApertura, const char *tagChiusura ) {
  180.     char *s = NULL;
  181.  
  182.     int err = TE_estrai_tag_stringa( &s, NULL, stringaDati,
  183.                                      etichettaTag, tagApertura, tagChiusura );
  184.  
  185.     if( kTEErr_NoErr == err ) {
  186.         char *fine, *sAux = '0'==s[0] && 'x'==s[1] ? s+2 : s;
  187.         long long eTmp = strtoll( sAux, &fine, 16 );
  188.  
  189.         if( sAux!=fine && '\0'==*fine )
  190.             *pEstratto = eTmp;
  191.         else err = kTEErr_NoInt;
  192.  
  193.         free( s );
  194.     }
  195.  
  196.     return err;
  197. }
  198.  
  199. const char *TE_descrizione_errore( int codice ) {
  200.     if( codice>=0 && codice<kTEErr_TotErrori )
  201.         return TE_ErrStr[codice];
  202.     else return "Errore non previsto.";
  203. }
  204.  
  205.  
  206. /// ===> FUNZIONI STATICHE <====================================================
  207.  
  208.  
  209. /*==============================================================================
  210. PARAMETRI
  211.     cont    (out) qui viene messo il puntatore alla sottostringa del contenuto
  212.     lCont   (out) la lunghezza della sottostringa del contenuto trovato
  213.     s       (in)  la stringa nella quale effettuare la ricerca
  214.     a       (in)  la stringa della clausola di apertura
  215.     la      (in)  la lunghezza della stringa della clausola di apertura
  216.     c       (in)  la stringa della clausola di chiusura
  217.     lc      (in)  la lunghezza della stringa della clausola di chiusura
  218.  
  219. N.B. NESSUN PARAMETRO VIENE VERIFICATO
  220.  
  221. VALORE DI RITORNO
  222.     Un codice di errore.
  223. ==============================================================================*/
  224.  
  225. static int TE_trova_contenuto( const char **cont, size_t *lCont,
  226.                                const char *s,
  227.                                const char *a, size_t la,
  228.                                const char *c, size_t lc ) {
  229.     const char *contTmp = NULL;
  230.     int aperto = 0;
  231.  
  232.     while( *s ) {
  233.         if( *s == *a || *s == *c ) {
  234.             int apertura, chiusura;
  235.  
  236.             if( (apertura=(0==strncmp(s,a,la))) ) {
  237.                 if( !aperto ) {
  238.                     aperto = 1;
  239.                     s += la;
  240.                     contTmp = s;
  241.                     continue;
  242.                 }
  243.  
  244.                 return kTEErr_NoFormato;
  245.             }
  246.  
  247.             if( (chiusura=(0==strncmp(s,c,lc))) ) {
  248.                 if( aperto ) {
  249.                     *cont  = contTmp;
  250.                     *lCont = s-contTmp;
  251.                     return kTEErr_NoErr;
  252.                 }
  253.  
  254.                 return kTEErr_NoFormato;
  255.             }
  256.         }
  257.  
  258.         ++s;
  259.     }
  260.  
  261.     return kTEErr_NoCont;
  262. }



File main.c
Codice sorgente - presumibilmente C++

  1. #include "tag_etichettati.h"
  2.  
  3. #define LMAX_ETICHETTA 255U
  4. #define LMAX_CLAUSOLE   31U
  5. #define LMAX_TIPODATO   31U
  6. #define Q_TIPIDATO       4U
  7.  
  8. const char *kNomeFileDati = "dati.txt";
  9. const char *kTipiDato[Q_TIPIDATO]={"stringa","intero","virgola","esadecimale"};
  10.  
  11. char *gDati = NULL;
  12. char gEtichetta[LMAX_ETICHETTA+1];
  13. char gApertura[LMAX_CLAUSOLE+1];
  14. char gChiusura[LMAX_CLAUSOLE+1];
  15. unsigned int gTipoDato = -1;
  16.  
  17. void chiedi_dati( void );
  18. void gestisci_estrazione_tag( void );
  19. int continua( void );
  20.  
  21. int main() {
  22.     int err = TE_carica_file( &gDati, NULL, kNomeFileDati );
  23.  
  24.     if( kTEErr_NoErr == err ) {
  25.         do {
  26.             chiedi_dati();
  27.             gestisci_estrazione_tag();
  28.         } while( continua() );
  29.     }
  30.  
  31.     if( gDati ) { free( gDati ); gDati = NULL; }
  32.  
  33.     if( kTEErr_NoErr != err ) printf( "ERRORE: " );
  34.     printf( "%s.\n\n", TE_descrizione_errore(err) );
  35.  
  36.     getchar();
  37.     return 0;
  38. }
  39.  
  40. void chiedi_stringa( char *buff, unsigned int lMax ) {
  41.     unsigned int l;
  42.  
  43.     do {
  44.         fgets( buff, lMax+1, stdin );
  45.  
  46.         l = strlen( buff );
  47.  
  48.         if( l>0 ) {
  49.             if( '\n' == buff[l-1] ) {
  50.                 buff[--l] = '\0';
  51.                 break;
  52.             }
  53.             else {
  54.                 while( '\n' != getchar() );
  55.                 printf( "Max %u caratteri, riprova: ", lMax-1 );
  56.                 continue;
  57.             }
  58.         }
  59.     } while(1);
  60. }
  61.  
  62. int continua( void ) {
  63.     char buff[4];
  64.  
  65.     chiedi_continua:
  66.  
  67.     printf( "Vuoi effettuare un altro test? (s/n) " );
  68.     chiedi_stringa( buff, 2 );
  69.  
  70.     if( 's'==*buff || 'S'==*buff )
  71.         return 1;
  72.     else if( 'n'==*buff || 'N'==*buff )
  73.         return 0;
  74.  
  75.     printf( "Non ho capito.\n" );
  76.     goto chiedi_continua;
  77. }
  78.  
  79. void chiedi_etichetta( void ) {
  80.     printf( "Etichetta: " );
  81.     chiedi_stringa( gEtichetta, LMAX_ETICHETTA );
  82. }
  83.  
  84. void chiedi_clausola_apertura( void ) {
  85.     printf( "Clausola d'apertura: " );
  86.     chiedi_stringa( gApertura, LMAX_CLAUSOLE );
  87. }
  88.  
  89. void chiedi_clausola_chiusura( void ) {
  90.     printf( "Clausola di chiusura: " );
  91.     chiedi_stringa( gChiusura, LMAX_CLAUSOLE );
  92. }
  93.  
  94. void chiedi_tipo_dato( void ) {
  95.     char strTipoDato[LMAX_TIPODATO+1];
  96.     unsigned int i;
  97.  
  98.     printf( "Tipo di dato: " );
  99.  
  100.     richiesta:
  101.     chiedi_stringa( strTipoDato, LMAX_TIPODATO );
  102.  
  103.     for( i=0; i<Q_TIPIDATO; ++i ) {
  104.         if(0==strcmp(kTipiDato[i],strTipoDato) ) {
  105.             gTipoDato = i;
  106.             break;
  107.         }
  108.     }
  109.  
  110.     if( Q_TIPIDATO==i ) {
  111.         printf( "Tipo di dato non valido, riprova: " );
  112.         goto richiesta;
  113.     }
  114. }
  115.  
  116. void chiedi_dati( void ) {
  117.     printf( "\n" );
  118.     chiedi_etichetta();
  119.     chiedi_clausola_apertura();
  120.     chiedi_clausola_chiusura();
  121.     chiedi_tipo_dato();
  122. }
  123.  
  124. void mostra_dati_globali( void ) {
  125.     printf( "\n" );
  126.     printf( "Etichetta:            %s\n", gEtichetta );
  127.     printf( "Clausola d'apertura:  %s\n", gApertura );
  128.     printf( "Clausola di chiusura: %s\n", gChiusura );
  129. }
  130.  
  131. void gestisci_estrazione_tag_stringa( void ) {
  132.     char *str = NULL;
  133.     size_t lStr = 0;
  134.  
  135.     int err = TE_estrai_tag_stringa( &str, &lStr, gDati,
  136.                   gEtichetta, gApertura, gChiusura );
  137.  
  138.     mostra_dati_globali();
  139.  
  140.     if( kTEErr_NoErr == err )
  141.         printf( "Contenuto del tag:    \"%s\"\n\n", str );
  142.     else printf( "Errore: %s.\n\n", TE_descrizione_errore(err) );
  143. }
  144.  
  145. void gestisci_estrazione_tag_intero( void ) {
  146.     long long intero;
  147.  
  148.     int err = TE_estrai_tag_intero( &intero, gDati,
  149.                   gEtichetta, gApertura, gChiusura );
  150.  
  151.     mostra_dati_globali();
  152.  
  153.     if( kTEErr_NoErr == err )
  154.         printf( "Contenuto del tag:    %lld\n\n", intero );
  155.     else printf( "Errore: %s.\n\n", TE_descrizione_errore(err) );
  156. }
  157.  
  158. void gestisci_estrazione_tag_virgola( void ) {
  159.     long double virgola;
  160.  
  161.     int err = TE_estrai_tag_virgola( &virgola, gDati,
  162.                   gEtichetta, gApertura, gChiusura );
  163.  
  164.     mostra_dati_globali();
  165.  
  166.     if( kTEErr_NoErr == err )
  167.         printf( "Contenuto del tag:    %llf\n\n", virgola );
  168.     else printf( "Errore: %s.\n\n", TE_descrizione_errore(err) );
  169. }
  170.  
  171. void gestisci_estrazione_tag_esadecimale( void ) {
  172.     long long intero;
  173.  
  174.     int err = TE_estrai_tag_esadecimale( &intero, gDati,
  175.                   gEtichetta, gApertura, gChiusura );
  176.  
  177.     mostra_dati_globali();
  178.  
  179.     if( kTEErr_NoErr == err )
  180.         printf( "Contenuto del tag:    %llx\n\n", intero );
  181.     else printf( "Errore: %s.\n\n", TE_descrizione_errore(err) );
  182. }
  183.  
  184. void gestisci_estrazione_tag( void ) {
  185.     switch( gTipoDato ) {
  186.         case 0: gestisci_estrazione_tag_stringa();     break;
  187.         case 1: gestisci_estrazione_tag_intero();      break;
  188.         case 2: gestisci_estrazione_tag_virgola();     break;
  189.         case 3: gestisci_estrazione_tag_esadecimale(); break;
  190.         default: puts( "Errore: tipo dato non riconosciuto.\n" );
  191.     }
  192. }



Perché ho messo qui il codice? Boh. Magari a qualcuno scappa qualche commento o, meglio, qualche suggerimento. Tenete sempre presente che per me tutto questo è un passatempo, non un mestiere -- non sono neanche lontamente uno "specialista".

Ultima modifica effettuata da AldoBaldo il 03/04/2020 alle 14:39


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Goblin (Member)
Expert


Messaggi: 375
Iscritto: 02/02/2011

Segnala al moderatore
Postato alle 21:58
Venerdì, 03/04/2020
Testo quotato

Postato originariamente da AldoBaldo:
Perché ho messo qui il codice? Boh. Magari a qualcuno scappa qualche commento o, meglio, qualche suggerimento. Tenete sempre presente che per me tutto questo è un passatempo, non un mestiere -- non sono neanche lontamente uno "specialista".



Su questo punto hai tutta la mia comprensione.
Cmq io sparo la cavolata dopo quasi 1 mese di clausura con moglie figli e cani, hai pensato a gestire oggetti JSON ???
In fondo il principo del formato JSON è CHIAVE:VALORE il che riconduce al tuo ETICHETTA:DATO.
In C puro non saprei come manipolarlo, ma sicuramente ci sarà in giro documentazione.
OK se ho detto una cavolata ... mi fustigo da solo ... tanto sono in clausura :blush::blush:

PS: Maestro AldoBaldo... la forza scorre forte nei nostri Padawan, ricorda
G.


Ibis redibis non morieris in bello
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 0:20
Sabato, 04/04/2020
Non ricordo più da parte di chi, ma un riferimento a questo JSON era già apparso in questi luoghi. Incuriosito, avevo cercato qualche informazione, ma ne avevo ricavato la sensazione di essere davanti a qualcosa di più articolato di quello che sarei stato in grado di "manipolare". Potrei provare a rivedere quelle informazioni oggi. Magari in questi anni ho assimiliato quanto serve per capirci di più. Sai che faccio? Cerco subito e torno a scrivere le mie impressioni.
Grazie per lo spunto.

===================

EDIT

Ho letto qualcosina.

Ora ricordo perché l'avevo scartato. Ci sono alcune cose che mi mettono "all'angolo". Cito testualmente dal testo che ho appena scorso:

1) "strutture possono essere annidate"
2) "raccolta di zero o più caratteri Unicode"
3) "sequenze di escape" (segue nutrito elenco)
4) esistono già svariate librerie e classi per gestire questo formato

1) leggere e interpretare strutture annidate mi mette in crisi, risolvere il problema richiede con ogni probabilità tecniche che uso a stento, che non padroneggio (ricorsione?)
2) non conosco i meccanismi per usare Unicode, che non ho mai usato
3) dovrei prendere in considerazione tutta una pletora di sequenze di escape, capirne il meccanismo
4) ...per poi ottenere qualcosa che è già stato fatto e rifatto infinite volte, cioè per "reinventare la ruota"

No, affrontare 'sto JSON non mi divertirebbe neppure oggi (e non so neppure se riuscirei ad arrivare all'obbiettivo che avevo in mente). Per i miei scopi (limitati) credo sia più semplice e diretta la strada che ho seguito. Ammesso che funzioni come ho in mente e non ci siano difetti che mandano tutto a rotoli.

Comunque, proprio in questo momento sto ancora leggendo altre pagine. Magari cambio idea, chissà.

P.S. La forza non so neppure più dove stia di casa. Più che a "Guerre stellari" sento di potermi rifare a questo:

https://it.wikipedia.org/wiki/Balle_spaziali

Ultima modifica effettuata da AldoBaldo il 04/04/2020 alle 0:41


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
Goblin (Member)
Expert


Messaggi: 375
Iscritto: 02/02/2011

Segnala al moderatore
Postato alle 1:05
Sabato, 04/04/2020
Testo quotato

Postato originariamente da AldoBaldo:


https://it.wikipedia.org/wiki/Balle_spaziali



Maestro AldoBaldo, vedo che hai anche tu l'anello,  il tuo Sforzo è come mio, vediamo come lo maneggi..

Ultima modifica effettuata da Goblin il 04/04/2020 alle 1:06


Ibis redibis non morieris in bello
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6404
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 8:46
Sabato, 04/04/2020
Potresti usare dei file .ini

Vecchia roba (sarebbe meglio un xml) ma ti potrebbe bastare per i tuoi scopi. E hai le api in windows. Come facevano tutti nei decenni passati prima che tu scoprissi questa necessita' e reinventassi la ruota

Vedi

WritePrivateProfileString
GetPrivateProfileString


Ultima modifica effettuata da nessuno il 04/04/2020 alle 8:47


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 9:22
Sabato, 04/04/2020
Nei file .ini mi sono in effetti imbattututo più volte, sono tanti i programmi che ne spargono qua e là, però non ho mai approfondito. E' un bel suggerimento, questa sero leggerò senz'altro qualcosa e ti dirò com'è andata. Ora devo andare a piantare le cipolle, se no mi germogliano nel sacchetto e si indeboliscono.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 700
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 23:10
Domenica, 05/04/2020
Piantate le cipolle! Taaaaante cipolle. Domani sera, tempo permettendo, vado giù di scalogno.

Ho pure trovato il tempo di vedere qualche informazione sul formato .ini. Non ne sono rimasto esaltato. Per i miei scopi limitati, continuo a preferire il mio metodo "ruspante".


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote