Newsgroup: it.comp.os.linux.development
Titolo: come separare 2 stringhe

salve ,
mi sono imbatutto in questo problema.
Io ricevo da un client esterno una stringa di dati che a volte
contiene degli altri caratteri prima della stringa vera e propria.
Questo mi crea numerosi problemi xke mi scombussola tutta
l'acquisizione dei dati...
Come posso risolvere questo problema eliminando tutti i caratteri
antecedenti alla mia stringa?
La mia stringa inizia sempre con 2 caratteri ben precisi.... questo
dovrebbe agevolare le cose... :D
Grazie

 dovrebbe agevolare le cose... :D
dovrebbe agevolarle, ma che succede se proprio quei due  caratter li
ritrovi nche nella robaccia che leggi prima?
poi, se specifchi il linguaggio è già un passo avanti
se fosse c
char letta[XXX],*p;
p = strstr(letta,"DUECARATTERI");

si scusa...
allora i dati li ricevo tramite un socket... il linguaggio e il c...
è difficile che il programma riceva altri 2 caratteri uguali prima
della stringa...
ho gia provato con il strstr e poi facevo un ciclo while fino a quando
non trovava '\0' ma
entrava in questo ciclo e non ne usciva piu'!!
io pensavo di prendere tutta la parte precedente e buttarla via... e
rimettere tutta la stringa pulita nella stessa variabile.
Grazie

 Questo mi crea numerosi problemi xke mi scombussola tutta
]zac[
Ehm .. è ambiguo ma dove e come la ricevi? con che linguaggio tratti la
cosa, come leggi e come vuoi l'uscita dei dati?
Insomma quei dettagli che consentono (forse) di capire qualcosa di più del
non funziona ...

 della stringa...
]zac[
Stabilizzare le stringhe ricevute sarebbe molto meglio, come sarebbe meglio
identificare con certezza l'inizio e la fine di una comunicazione
(caratteri di fine, lunghezza fissa).
Comunque potresti settare un flag che segnala che non hai ancora letto i
caratteri iniziali, scartare tutte le stringhe o parti delle stringhe lette
che non iniziano con i caratteri cercati, poi setti il flag e quindi
aggiungi tutto le restanti stringhe lette
Per il resto dipende da quello che hai per le mani, una lettura ciclica, una
lettura su comando (quindi ad ogni comando azzeri il flag), ecc. .
Non sapendo come funziona quello che stai usando è possibile che i caratteri
iniziali sia suddivisi su due letture, ne qual caso la cosa si complica.
Auguri.

mi sono creato un server che deve ricevere dei dati da altri pc
tramite internet.
questi dati poi li prendo con un recv , lo metto in una variabile e lo
analizzo...
A volte capita di ricevere dei caratteri incomprensibili prima della
stringa contenente i dati che mi interrompono il programma; ho bisogno
di eliminare queste cosa precedenti alla stringa.
Io avevo pensato di fare questo:
 while(strncmp("@@",echoBuffer,2)!=0)
{
//cerca carattere e inizia ciclo
strncpy(echoBuffer,&echoBuffer[1],
((strlen(echoBuffer))-1));
//copia saltanto il primo carattere all'interno della stessa variabile
}
ma mi dà errore....
Segmentation fault
come posso fare?

 come posso fare?
Anche io non ho capito il problema e se davvero questa sia la soluzione.
ANche io credo che dovresti allinearti bene al record in ricezione, che
se arriva spezzato fra piu' letture, dovrai ricomporre usando un buffer
con un automa a stati finiti.
Nello specivico di cio ' che hai postato .... vorrei dire alcune cose:
In C a differenza di altri linguaggi con gestione della memoria automatica,
si possono fare cose molto piu' divertenti per gestire la memoria.
Sono pochi i casi in cui devi copiare una stringa.
Se hai la stringa echoBuffer e sei interessato alla stringa di due char
piu' avanti, puoi, supponendo char * echoBuffer, usare per i tuoi
scopi la stringa (echoBuffer+2). Grazie all' algebra dei puntatori del C,
la cosa che lo rende il linguaggio piu amato da... (da me sicuramente!)
l' espressione (echoBuffer + 2) restituisce un puntatore al tipo puntato
spostato di 2 volte sizeof del tipo base. (char ha sizeof 1 su qualunque
implementazione).
Quindi niente costose copie di stinga, almento in questo caso. Da come
descrivi il problema pero' questo sembra sono un workaround, ma credo
ci sia un errore nell' implementazione del protocollo. Magari poi
spiegerai.
Altra cosa relativa a quanto hai postato:
strncpy(echoBuffer,&echoBuffer[1], ((strlen(echoBuffer))-1));
In caso di dubbio sulle precedenze degli operatori, meglio usare le
parentesi, anche se in questo caso credo vadano bene...
strncpy(echoBuffer,&(echoBuffer[1]), ((strlen(echoBuffer))-1));
comunque uguale a:
strncpy(echoBuffer,(echoBuffer +1), ((strlen(echoBuffer))-1));
ma strncpy standard ANSI NON VA BENE!!!
man 3 memmove
DESCRIPTION
       The  memmove()  function  copies n bytes from memory area src to
memory
       area dest.  The memory areas may overlap: copying takes place as
though
       the  bytes in src are first copied into a temporary array that does
not
       overlap src or dest, and the bytes are then copied from  the 
temporary
       array to dest.
Ciao
Roberto
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

        array to dest.
Aggiungo che io piuttosto che usare memmove che non so' che costo
computazionale effettivamente ha (magari fa veramente una copia temporanea)
la funzione appropriata me la scrivo da solo al momento.
size_t len;
len = strlen(echoBuffer) -1;
for(i=0;i<len;i++) echoBuffer[i] = echoBuffer[i+1];
E' vero che le funzioni di libreria possono essere ottimizzate anche in
assembler, ma e' necessario sapere che una reimplementazione puo' essere
piu' efficiente o no.
Ciao
Roberto.


 come posso fare?
Inoltre sei sicuro che echoBuffer sia terminato con '

ciao ho fatto come mi hai detto tu......
ho aggiunto anche davanti un ciclo while perche' io non so di preciso
quanti valori precedenti ci sono alla mia stringa dati
size_t len;
while(strncmp("@@",echoBuffer,2)!=0){
	len = strlen(echoBuffer) -1;
	for(i=0;i<len;i++)
	echoBuffer[i] = echoBuffer[i+1];
}
ma cosi' facendo i 2 caratteri che indicano l'inizio della stringa(@@)
diventano 3!!! (@@@)...
ti faccio un esempio visto che non riesco a farvi capire il mio
problema,...
io tramite socket ricevo questa stringa....
�   @@STRINGA_DATI_CHE_MI_INTERESSANO
io voglio eliminare questi (�   ) o qualsiasi altro carattere
precedente alle mie @@
se uso quello che mi hai detto tu la stringa dopo mi viene:
@@@STRINGA_DATI_CHE_MI_INTERESSANO
e non sono riuscito a capire il perche'!!
spero di essermi fatto capire...
grazie a tutti

 Segmentation fault
]zac[
Andando molto a occhio è il classico problema di lettura a ''pezzi'' di una
stringa più grande del buffer disponibile, quindi è possibile che la
stringa non sia terminatadal '\0'.
In questo caso basta controllare se esiste ed eventualmente aggiungerlo
prima di trattare la stringa e rimuovere l'aggiunta dalla lettura prima di
ricomporre la stringa.
E' consigliabile caldamente leggere molto meglio la documentazione delle
funzioni di lettura per capire come si comportano nei vari casi, ed
caldamente consigliabile capire e come mai si hanno letture con dati
random.


il terminatore di stringa('\0') l'ho gia messo........

 grazie a tutti
Non riesco ora a fare delle simulazioni, ma proviamo a fare delle ipotesi
ANCHE SE RIBADISCO DI PREFERIRE NON COPIARE LA STRINGA!
il funzionamente di strlen implica la presenza di un '\0' quindi la
stringa interessante e integra per te e' "@@ROBA_CHE_INTERESSA\0"
tuttavia bel buffer potesti avere piu' stringe interessanti separate
da "\0@@" la terminazione di una e l' inizio dell' altra.
Spostando strlen -1 char dalla posizione 1 alla posizione 0, da dove
hai calcolato strlen() ti copi anche la prima "@" della secoda stringa
interessante. quindi ti ho mandato un bug, ma io speravo piu' che altro
di persuaderti a NON USARE QUESTA TECNICA. A pensarci bene, devi spostare
indietro strlen() - 2 per far funzionare l' algoritmo che gia' ho
criticato prima. Oppure con strstr() trovi la posizione dove si trovano
le due "@@" (mi fa ridere le due @@) e sposti una sola volta il tutto,
prestando attenzione a non sovrascrivere il carattere di terminazione.
MA QUANDO CON strstr HAI TROVATO DOVE INIZIA la stringa interessante,
PERCHE' LA DOVRESTI SPOSTARE?



il mio consiglio spassionato è, se hai scritto tu il client, verifica perchè 
manda dati random. Se stai comunicando tramite TCP/IP non è il trasporto che 
introduce caratteri random bensì un bug nel software.
-- 
SF
Games are very educational. Scrabble teaches us vocabulary, Monopoly teaches 
us cash-flow management, and Dungeons & Dragons teaches us to loot dead bodies.


io non ho alcun problema ad usare un altro sistema x pulirmi la
stringa.... ma non mi viene in mente niente altro per farlo.... :(
non sono ancora troppo esperto di c e non conosco bene ancora tutte le
funzioni... questa mi sembrava la piu' semplice dal punto di vista
logico...
se mi sai consigliare altri comandi o modo x farlo, io sono ben
disposta ad usarli :D!!
la stringa mi serve pulita xke dopo mi faccio delle conversioni e mi
risulta piu' scomodo farlo con una parte iniziale che non mi interessa
e varia di volta in volta....
Grazie.


wrote:

probabilmente è un problema dell'altro programma... quello che mi
manda i dati... ma quello non lo sto facendo io e non posso
intervenire... :(

 
Ti hanno semplicemente detto che non serve spostare il contenuto del tuo
array. Ti basta cercare il punto in cui si trova la sequenza interessata, e
da lì in poi usare il puntatore a quella posizione come se il tuo array
iniziasse lì. L'unico motivo per cui tu voglia spostare il contenuto è la
necessità continuare a utilizzare l'array per aggiungere dati in coda senza
sprecare lo spazio iniziale. Diversamente, non c'è ragione.
Riassumendo.
Diciamo che 'echoBuffer' punta a una sequenza di caratteri di
lunghezza 'bufferLen'. 'pos' è un 'char*'.
     /* cerco la posizione di "@@" */
     pos = memmem( echoBuffer, bufferLen, "@@", 2 );
     if( pos ) 
     {          bufferLen -=  pos - echoBuffer;
                /* ora, se non voglio spostare i dati... */
                echoBuffer = pos;
               /* ... altrimenti, se voglio spostare i dati... */
                memmove( echoBuffer, pos, bufferLen );
     }
Max

 intervenire... :(
allora digli che è un incompetente e che lo metta a posto! :)


Max..  ho fatto come mi hai detto tu...
char *pos;
size_t bufferLen;
bufferLen = strlen(echoBuffer);
// cerco la posizione di "@@"
*pos = memmem( echoBuffer, bufferLen, "$$", 2 );
 if( pos )
     {
bufferLen -=  pos - echoBuffer;
memmove( echoBuffer, pos, bufferLen );
     }
ma mi da un continuo
Segmentation fault
ho dovuto aggiungere un *pos=memmem xke se no mi dava errore...
ma questo Segmentation fault non riesco a capire cosa lo genera...
eppure non mi sembra che sfori di dimenisione da nessuna parte...
purtroppo queste funzioni memmem memmove non le ho mai usate....
Grazie

 ma questo Segmentation fault non riesco a capire cosa lo genera...
(probabilmente) vedi commento iniziale.


 ho dovuto aggiungere un *pos=memmem xke se no mi dava errore...
Capisco. Quando hai un errore di compilazione, tu aggiungi degli asterischi
a caso. E poi ti stupisci se il programma muore. :)
L'alterisco non c'entra nulla. Noi vogliamo assegnare un valore a 'pos' che
è un puntatore. 'memmem' restituisce un void* che, in C, puoi benissimo
assegnare a 'pos'. Se il tuo programma non compila, vuol dire che non hai
incluso l'header con la dichiarazione. La manpage di 'memmem' ti dirà come
fare.
Ad ogni modo, 'memmem' è un'estensione GNU. In alternativa, puoi usare
'strstr', che però si aspetta un array null-terminated.
Max