Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [c] ricerca e sostituzione

    ragazzi dovrei fare una func (anche con allocazione statica) che sostituisca tutte le occorrenze trovate di una stringa con un'altra stringa data in input... le 2 stringhe possono avere lunghezza differente

    quindi dopo la sostituzione si dovrebbe prevedere di spostare in avanti o indietro in base alla lunghezza delle stringhe...

    qualcuno pratico di string.h mi scrive la funzioncina? ^^

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462

    Re: [c] ricerca e sostituzione

    Originariamente inviato da xnavigator
    qualcuno pratico di string.h mi scrive la funzioncina? ^^
    Mi sa che queste richieste non sono gradite nel forum ...

    Mostra impegno e prova a scrivere tu qualcosa e solo se hai difficolta' allora interpella il forum ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    hai perfettamente ragione...

    più tardi provo a scrivere qualocsa, però spesso (io sono il primo nella sezione php) che mi piace scrivere il codice anche a chi lo chiede cosi brutalmetne

    thx anyway

  4. #4
    Ma la sostituzione deve essere fatta in loco o la funzione può/deve restituire una nuova stringa allocata all'uopo?
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Originariamente inviato da xnavigator
    però spesso (io sono il primo nella sezione php) che mi piace scrivere il codice anche a chi lo chiede cosi brutalmetne
    Infatti, ho detto che non e' una cosa gradita (io sono tra quelli che non gradiscono perche' non lo trovo "educativo" e troppo "comodo") ma vedrai che qualcuno che non la pensa così, ti scriverà tutto il codice ...

    In ogni caso, resta la convinzione che anche un minuto impiegato a provarci ti aiuta tantissimo ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    Originariamente inviato da MItaly
    Ma la sostituzione deve essere fatta in loco o la funzione può/deve restituire una nuova stringa allocata all'uopo?
    no puoi anceh utilizzare una nuova stringa settata in precedenza...
    non dovendo fare cose dinamiche si può anche fare:

    char newStr[30];



    (tnato verranno passate solo frasi piccole)

  7. #7
    Ti do uno spunto: alloca la stringa di output come preferisci, e usa due puntatori, uno per la lettura dalla stringa originale e uno per la scrittura dalla stringa di destinazione (è un metodo estremamente utilizzato quando si effettuano sostituzioni sulle stringhe). Quando nel ciclo incontrerai una stringa da sostituire (individuabile con la funzione strncmp) potrai copiare direttamente nella stringa di destinazione la stringa sostitutiva (strcpy), spostando avanti (di un numero di caratteri differente, ovviamente) i due puntatori in modo che passino oltre la stringa da sostituire (nel caso del puntatore in lettura) e quella sostitutiva (nel caso del puntatore in scrittura). Nel caso di caratteri da copiare "paro paro", invece, ti basterà fare *writePtr=*readPtr.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    ok fatto it works:
    codice:
    	char *text= "Nel mezzo del cammin di nostra vita al mezzo dove";
    	char *search = "mezzo";
    	char *replace = "centrale";
    	char *currentSearch = text;
    	char *newText;
    
    	unsigned short iText=0;
    	unsigned short iNewText=0;
    
    	newText = (char *)calloc(1,sizeof(char));
    
    	//printf("Text=>%d\nnewText=>%d\n\n",text,newText);
    	while( (currentSearch=strstr(text+iText,search)) != NULL )  {
    	
    
    		newText = (char *)realloc(newText, ( strlen(newText)+strlen(search)+strlen(text)-iText-strlen(search) ) * sizeof(char) );
    		
    		strncat(newText+iNewText,text+iText,currentSearch-( text+iText ));
    		
    		strcpy( newText+strlen(newText),replace );
    		
    		
    		iNewText += currentSearch-( text+iText ) + strlen(replace);
    
    		iText+=currentSearch-(text+iText)+strlen(search);
    		
    		//printf("cS=>%d \n iNewText=>%d \n iText=>%d \n",currentSearch,iNewText,iText);
    	}
    
    	strcpy( newText+iNewText,text+iText );
    	
    
    	printf("S:%s\n",newText);
    però sembra quasi come se avessi scritto del codice aggiuntivo non so perchè..
    qualche errore di cattiva programmazione?

  9. #9
    Così al volo non mi pare che ci sia nulla di sbagliato (ripeto, l'ho controllato solo di sfuggita), una considerazione che mi viene subito però è che per velocizzare molto il tuo algoritmo potresti evitare di richiamare strlen ogni volta sulle stringhe che rimangono costanti (come search e replace), e piuttosto mettere questi valori in una variabile. Inoltre non ho ben capito che conti fai qui:
    codice:
    		newText = (char *)realloc(newText, ( strlen(newText)+strlen(search)+strlen(text)-iText-strlen(search) ) * sizeof(char) );
    (tra l'altro strlen(search) è aggiunto e sottratto, per cui è assolutamente ininfluente); se ho capito bene come funziona il tuo algoritmo basterebbe
    codice:
    		newText = (char *)realloc(newText, ( strlen(newText)+strlen(replace) ) * sizeof(char) );
    .
    Inoltre, se ho capito cosa sia iNewText, credo che quella strncat potrebbe essere una strncpy.
    Infine, la continua chiamata a realloc potrebbe penalizzare le performance; in alcuni casi potrebbe essere meglio prevedere il caso peggiore e allocare il massimo di memoria che potrebbe essere necessaria, oppure utilizzare un approccio ibrido (allocazione del massimo se è sotto tot KB oppure riallocazione di volta in volta).
    Un esempio con questo approccio:
    codice:
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <stddef.h>
    
    char * ReplaceString(const char * Str, const char * Search, const char * Replace)
    {
        /* Lunghezza della stringa da cercare */
        size_t searchLength=strlen(Search);
        /* Lunghezza della stringa sostitutiva */
        size_t replaceLength=strlen(Replace);
        /* Lunghezza della stringa in cui verrà effettuata la ricerca */
        size_t strLength=strlen(Str);
        /* Puntatore alla nuova stringa da restituire */
        char * ret;
        /* Puntatore al carattere di Str attualmente letto */
        const char * readPtr;
        /* Puntatore al carattere di ret attualmente scritto */
        char * writePtr;
        /* Dimensioni della stringa da restituire */
        size_t retSize;
        /* Dimensione massima di ret se viene allocata preventivamente (e non riallocata ad ogni sostituzione) */
        const size_t retMaxSize=8192;
        /* Flag che indica l'approccio utilizzato (allocazione immediata o riallocazione ad ogni sostituzione) */
        enum AllocMode
        {
            inAdvance,
            onDemand
        } allocMode;
        /* Verifica se per caso è stata passata qualche stringa nulla */
        if(!(searchLength&&replaceLength&&strLength))
            return NULL;
        /* Calcola le dimensioni della stringa da allocare nel caso peggiore */
        retSize=strLength+((replaceLength<searchLength)?0:(strLength/searchLength*(replaceLength-searchLength)))+1;
        /* Controlla se le dimensioni così calcolate sforano il nostro limite
           se retSize==strLength significa che Replace è più corta di Search, per cui
           non dovremo riallocare niente (si fa ricadere nel caso allocMode=onDemand */
        if(retSize>retMaxSize && retSize!=strLength)
        {
            /* In questo caso riallocheremo la memoria ogni volta
               Intanto allochiamo in tutto quanta memoria ci serve per effettuare
               una copia senza sostituzioni della stringa (il minimo indispensabile) */
            retSize=strLength+1;
            allocMode=onDemand;
        }
        else
            allocMode=inAdvance;
        /* Alloca la memoria */
        if((ret=malloc(retSize))==NULL)
            return NULL;
        /* Non si sbaglia mai a NUL-terminare i buffer, anche se vuoti */
        *ret=0;
        /* Cicla su ogni carattere */
        for(readPtr=Str,writePtr=ret;*readPtr;readPtr++,writePtr++)
        {
            /* Verifica se al carattere corrente c'è la stringa da cercare */
            if(!strncmp(readPtr,Search,searchLength))
            {
                /* Se l'allocazione è on-demand rialloca ret */
                if(allocMode==onDemand)
                {
                    /* Salva l'offset tra ret e writePtr */
                    ptrdiff_t writeOffset=writePtr-ret;
                    /* Rialloca la memoria */
                    if((ret=realloc(ret,retSize+replaceLength))==NULL)
                        return NULL;
                    /* Aggiorna retSize */
                    retSize+=replaceLength;
                    /* Aggiorna writePtr (qualora fosse cambiato ret) */
                    writePtr=ret+writeOffset;
                }
                /* Copia la stringa sostitutiva in fondo alla nuova stringa */
                strcpy(writePtr,Replace);
                /* Aggiorna i puntatori */
                writePtr+=replaceLength-1;
                readPtr+=searchLength-1;
            }
            else
            {
                /* Copia il carattere */
                *writePtr=*readPtr;
            }
        }
        /* Non si sbaglia mai a NUL-terminare i buffer */
        *writePtr=0;
        /* Se è stata allocata memoria in eccesso, la dealloca */
        ret=realloc(ret,strlen(ret)+1);
        return ret;    
    }
    
    int main()
    {
        char * str;
        str=ReplaceString("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean scelerisque, justo id ultrices congue, sapien elit sollicitudin enim, id tempor mi felis vitae magna. Maecenas at congue lorem. Aenean in leo eget ipsum mattis lacinia ut at enim. Suspendisse dolor odio, cursus vel volutpat eget, convallis quis felis. Sed placerat magna arcu, eu posuere leo. Donec dolor est, posuere vitae porta eget, egestas sed sem. Morbi tempor facilisis felis ut iaculis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc sit amet nisi nec velit volutpat venenatis. Vestibulum placerat, augue a venenatis blandit, neque justo ultricies eros, in tristique velit orci non libero.","a","zuzzurellone");
        if(str==NULL)
        {
            fputs("Errore",stderr);
        }
        else
        {
            puts(str);
            free(str);
        }
        return 0;
    }
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    mitaly potevi scriverla prima invece di aspettare che la facessi io








Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.