Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Split stringa in C o Bash ?
Forum - C/C++ - Split stringa in C o Bash ?

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 1:00
Giovedì, 01/01/1970
Ciao ho un problema con le stringhe: devo ricavare username e password da un file di configurazione del tipo:

<config>
<rule1>400</rule1>
<username>nome</username>
<something>boh</something>
<password>secret</password>
</config>

Forse ho trovato il modo di farlo, ma il programma mi va in SegFault e non riesco a capire perchè (gcc compila senza warnings).

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main()
  5. {
  6. char *a, *b, *c;
  7. a = strstr("aa<aa><username>admin</username>wdw","username");
  8. a = strstr(a,">");
  9. b = strstr(a,"<");
  10. size_t n = strlen(a) - strlen(b);
  11. strncpy(c,a,n);
  12. printf("%s\n",c);
  13.  
  14. a = strstr(a,"password");
  15. a = strstr(a,">");
  16. b = strstr(a,"<");
  17. n = strlen(a) - strlen(b);
  18. strncpy(c,a,n);
  19. printf("%s\n",c);
  20.  
  21. return 0;
  22. }



Non so cosa sbaglio nel codice, qualche illuminazione?

-- PS ---
Per me va anche meglio se mi dite come fare la stessa cosa in bash!
Voglio dire, lo split in bash riesco a farlo solo usando come delimitatore un carattere, mentre a me servirebbe inserire una stringa:
Cioè
Codice sorgente - presumibilmente Plain Text

  1. tmp=`echo $config | cut -d'<username>' -f2`


Mi da errore perchè  <username> è una stringa e bisogna usare un carattere per il delimitatore...

PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2763
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 17:18
Lunedì, 31/08/2009

è un problema più complesso di quello che sembra, ad ogni modo guarda questo parser:

http://www.codeguru.com/cpp/data/data-misc/xml/article.php ...



Ingegnere Informatico
https://ldlagency.it
PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 1:03
Venerdì, 11/09/2009
Grazie ma non ho risolto, al progetto che mi hai linkato gli ho dato una letta veloce, ma il codice è abbastanza lungo: a me serviva giusto una funzione.

NB: Non sono pigro ma il progetto non c'entrava comunque con la mia richiesta

Grazie,
aspetto qualche altra soluzione

Va bene anche se mettete a posto il codice che ho postato sopra, evitando il segfault!
Comunque è C, non C++

Ultima modifica effettuata da il 11/09/2009 alle 1:08
PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2763
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 11:40
Venerdì, 11/09/2009
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int GetField(char *pContent, char *pField, char *Buff, int iLen);
  6.  
  7. int main(int argc, char *pArgv[]) {
  8.  
  9.         int iRet;
  10.         char pBuff[32];
  11.  
  12.         char *pFileContent = "<config><rule1>400</rule1><username>nome</username><something>boh</something><password>secret</password></config>";
  13.        
  14.         iRet = GetField(pFileContent, "username", pBuff, 32);
  15.        
  16.         if (!iRet) {
  17.  
  18.                 printf("Unable to find 'username' field\n");
  19.  
  20.         } else {
  21.  
  22.                 printf("Username: %s\n", pBuff);
  23.  
  24.         }
  25.  
  26.         iRet = GetField(pFileContent, "password", pBuff, 32);
  27.  
  28.         if (!iRet) {
  29.  
  30.                 printf("Unable to find 'password' field\n");
  31.  
  32.         } else {
  33.  
  34.                 printf("Password: %s\n", pBuff);
  35.  
  36.         }      
  37.  
  38.         iRet = GetField(pFileContent, "pippo", pBuff, 32);
  39.  
  40.         if (!iRet) {
  41.  
  42.                 printf("Unable to find 'pippo' field\n");
  43.  
  44.         } else {
  45.  
  46.                 printf("Pippo: %s\n", pBuff);
  47.  
  48.         }
  49.  
  50.         system("PAUSE");
  51.                
  52.         return 0;
  53. }
  54.  
  55. int GetField(char *pContent, char *pField, char *pBuff, int iLen) {
  56.  
  57.         char *p, *pBeg, *pEnd;
  58.  
  59.         memset(pBuff, 0, iLen);
  60.  
  61.         // Look for the opening tag
  62.         p = strstr(pContent, pField);
  63.  
  64.         if (!p) return 0;
  65.  
  66.         // Go beyond the field name
  67.         p += strlen(pField);
  68.  
  69.         // Go Beyond spaces/newlines/etc.. till '>'
  70.         while(*p && *p != '>') p++;
  71.  
  72.         // EOF
  73.         if (!*p) return 0;
  74.  
  75.         // Beginning of field value
  76.         pBeg = ++p;
  77.  
  78.         // Look for the closing tag, it should match the opening one
  79.         pEnd = strstr(pBeg, pField);
  80.  
  81.         // EOF
  82.         if (!pEnd) return 0;
  83.  
  84.         // Check malformed XML
  85.         if ((*(pEnd - 1) != '/') || (*(pEnd - 2) != '<') | (*(pEnd + strlen(pField)) != '>')) return 0;
  86.  
  87.         // Backwards '</'
  88.         pEnd -= 2;
  89.  
  90.         // Copy the extracted string value (length capped if needed)
  91.         strncpy(pBuff, pBeg, (iLen < (pEnd - pBeg)) ? (iLen - 1) : (pEnd - pBeg));
  92.  
  93.         return 1;
  94.  
  95. }



è un parser BASE di XML che estrae solo i valori compresi tra due tag, è in grado di capire se l'xml non è ben formattato. Non supporta gli attributi ed è case sensitive.

EDIT: Perchè non mi colora la sintassi?

Ultima modifica effettuata da HeDo il 11/09/2009 alle 12:21


Ingegnere Informatico
https://ldlagency.it
PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 14:58
Venerdì, 11/09/2009
Grazie mille, ottimo!! A parte il system("PAUSE); ... programmi su windows?
Credo che tu intendessi la funzione getchar()... credo che anche su windows ci sia, o almeno una simile.

Grazie comunque ciao

---- Edit ----
un'altra cosa: nella riga

Codice sorgente - presumibilmente Plain Text

  1. iRet = GetField(pFileContent, "username", pBuff, 32);



e in

Codice sorgente - presumibilmente C/C++

  1. char pBuff[32];



32 sta per la lunghezza della stringa? Occorre cambiarlo a seconda della stringa, cioè della lunghezza del file xml?

Ultima modifica effettuata da il 11/09/2009 alle 15:08
PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2763
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 16:00
Venerdì, 11/09/2009
Testo quotato

Postato originariamente da TheWorm:

Grazie mille, ottimo!! A parte il system("PAUSE); ... programmi su windows?
Credo che tu intendessi la funzione getchar()... credo che anche su windows ci sia, o almeno una simile.

Grazie comunque ciao

---- Edit ----
un'altra cosa: nella riga

Codice sorgente - presumibilmente Plain Text

  1. iRet = GetField(pFileContent, "username", pBuff, 32);



e in

Codice sorgente - presumibilmente C/C++

  1. char pBuff[32];



32 sta per la lunghezza della stringa? Occorre cambiarlo a seconda della stringa, cioè della lunghezza del file xml?



si l'ho fatto sotto windows, e la GetField ha come parametri: il contenuto del file xml, il campo da cercare, un buffer nel quale mettere il valore del campo e la lunghezza di questo buffer.

dovrebbe funzionare tutto senza problemi anche sotto linux, testa e fammi sapere :)


Ingegnere Informatico
https://ldlagency.it
PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2763
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 17:00
Venerdì, 11/09/2009
EDIT: doppio post

Ultima modifica effettuata da HeDo il 11/09/2009 alle 17:01


Ingegnere Informatico
https://ldlagency.it
PM Quote
Avatar
()
Newbie


Messaggi:
Iscritto:

Segnala al moderatore
Postato alle 19:57
Venerdì, 11/09/2009
Grazie mille ho risolto subito con poche modifiche: ecco il parser a cui bisogna passare una stringa o il contenuto di un file come arg1 e il campo da ricercare come arg2.
Ex:
./xmlparse "<config><username>tony</username><password>secret123</password></config>" username
./xmlparse `cat config.xml` username

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int GetField(char *pContent, char *pField, char *Buff, int iLen);
  6.  
  7. int main(int argc, char *pArgv[]) {
  8.  
  9.     if(argc < 3) {
  10.         printf("Use: %s xmlstring desired_field\n", pArgv[0]);
  11.         return -1;
  12.     }
  13.  
  14.     char *pFileContent = pArgv[1];
  15.     char *pField = pArgv[2];
  16.     int strln = strlen(pFileContent);
  17.     int iRet;
  18.     char pBuff[strln];
  19.    
  20.     iRet = GetField(pFileContent, pField, pBuff, strln);
  21.    
  22.     if (!iRet) {
  23.         printf("Unable to find '%s' field\n", pField);
  24.     } else {
  25.  
  26.         printf("%s: %s\n", pField, pBuff);
  27.     }
  28.      
  29.     return 0;
  30. }
  31.  
  32. int GetField(char *pContent, char *pField, char *pBuff, int iLen) {
  33.  
  34.     char *p, *pBeg, *pEnd;
  35.  
  36.     memset(pBuff, 0, iLen);
  37.  
  38.     // Look for the opening tag
  39.     p = strstr(pContent, pField);
  40.  
  41.     if (!p) return 0;
  42.  
  43.     // Go beyond the field name
  44.     p += strlen(pField);
  45.  
  46.     // Go Beyond spaces/newlines/etc.. till '>'
  47.     while(*p && *p != '>') p++;
  48.  
  49.     // EOF
  50.     if (!*p) return 0;
  51.  
  52.     // Beginning of field value
  53.     pBeg = ++p;
  54.  
  55.     // Look for the closing tag, it should match the opening one
  56.     pEnd = strstr(pBeg, pField);
  57.  
  58.     // EOF
  59.     if (!pEnd) return 0;
  60.  
  61.     // Check malformed XML
  62.     if ((*(pEnd - 1) != '/') || (*(pEnd - 2) != '<') | (*(pEnd + strlen(pField)) != '>')) return 0;
  63.  
  64.     // Backwards '</'
  65.     pEnd -= 2;
  66.  
  67.     // Copy the extracted string value (length capped if needed)
  68.     strncpy(pBuff, pBeg, (iLen < (pEnd - pBeg)) ? (iLen - 1) : (pEnd - pBeg));
  69.  
  70.     return 1;
  71.  
  72. }


PM Quote
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2763
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 2:07
Sabato, 12/09/2009
ottimo :k:


Ingegnere Informatico
https://ldlagency.it
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo