Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2002
    Messaggi
    1,202

    [C] Stringa che non si cancella

    Ciao a tutti, ho questo problema.

    Ho una variabile globale messaggio, una stringa da stampare a schermo. La variabile è dichiarata nel main e usata in più file, mediante l'uso di extern.

    L'idea è di cancellare la stringa prima di scriverne una nuova, ossia quando cambia il messaggio da stampare a video.

    Il problema è che la stringa non si cancella, rimane lì, e se quella nuova è più corta la sovrascrive parzialmente.

    Ad esempio:

    - stampa messaggio="MESSAGGIO 1"
    - cancella messaggio
    - copia "MEX 2" in messaggio
    - stampa messaggio
    - mi viene stampato "MEX 2GGIO 1"

    Questo avviene sia usando un array di dimensione fissa sia usando la memoria dinamica.

    codice:
    char messaggio[100];
    if(strlen(messaggio)>0){ 
    	puts("resetting messaggio"); 
    	for(tmp=0;tmp<strlen(messaggio);tmp++) messaggio[tmp]='\0'; 			
    }
    codice:
    char* messaggio=NULL;
    if (messaggio!=NULL) free(messaggio);
    messaggio=malloc((1+strlen(d_words[34]))*sizeof(char));
    [...]
    puts(messaggio);
    free(messaggio);
    messaggio=NULL;
    Da notare che, nel primo caso, se al posto di '\0' uso ad esempio '-' la nuova stringa sarà "MEX 2------", quindi prende il comando ma è come se interpretasse '\0' come 'lascia invariato'.

    Idee?
    Debian GNU/Linux sid
    Publishing a theory should not be the end of one's conversation with the universe, but the beginning. (Eric S. Raymond)
    Kernel 2.6.14-ck1

  2. #2
    Utente di HTML.it L'avatar di Mashin
    Registrato dal
    Jul 2010
    Messaggi
    187
    Domanda. Perche' il reset della variabile nello step
    codice:
    char messaggio[100];
    if(strlen(messaggio)>0){ 
    	puts("resetting messaggio"); 
    	for(tmp=0;tmp<strlen(messaggio);tmp++) messaggio[tmp]='\0'; 			
    }
    lo fai fino a tmp<strlen(messaggio) e non fino a 99 resettando cosi' tutta la stringa in ogni sua parte?

  3. #3
    Posta il codice in cui copi il secondo messaggio nella stringa.
    Per inciso, in genere se riutilizzi una stringa per un altro messaggio non è necessario cancellarla, basta copiarci sopra il nuovo messaggio (che ovviamente dovrà essere NUL-terminato).
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2002
    Messaggi
    1,202
    @Mashin: boh, faccio il numero minore di clicli utili a cancellarmi la parte che mi interessa cancellare

    @MItaly: la scrittura nella stringa avviene sempre con una strncpy()
    Debian GNU/Linux sid
    Publishing a theory should not be the end of one's conversation with the universe, but the beginning. (Eric S. Raymond)
    Kernel 2.6.14-ck1

  5. #5
    Posta il codice che usi, perché secondo me il problema sta lì.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    466

    Re: [C] Stringa che non si cancella

    Originariamente inviato da Kamui
    - stampa messaggio="MESSAGGIO 1"
    - cancella messaggio
    - copia "MEX 2" in messaggio
    - stampa messaggio
    - mi viene stampato "MEX 2GGIO 1"
    ...
    la scrittura nella stringa avviene sempre con una strncpy()
    Devi passare il valore di strlen(messaggio) (o (strlen(src) +1 ) ma è meglio la prima opzione) come 3º parametro della strncpy

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2002
    Messaggi
    1,202
    Giusto! Mi mancava un +1!

    Ora sembra funzionare:

    codice:
    if (alertMsg!=NULL) free(alertMsg);
    alertMsg=malloc((1+strlen(d_words[34]))*sizeof(char));
    strncpy(alertMsg,d_words[34],strlen(d_words[34])+1);
    Debian GNU/Linux sid
    Publishing a theory should not be the end of one's conversation with the universe, but the beginning. (Eric S. Raymond)
    Kernel 2.6.14-ck1

  8. #8
    Utente di HTML.it
    Registrato dal
    Jul 2010
    Messaggi
    466
    Originariamente inviato da Kamui
    Giusto! Mi mancava un +1!
    Comunque io ti consiglio
    codice:
    strncpy(alertMsg, d_words[34], strlen(alertMsg));
    così che i restanti bytes di memoria vengono lasciati NUL e non rimangono "sporchi"..

  9. #9
    Non capisco perché usate strncpy con il numero di caratteri della stringa da copiare... a quello ci pensa già da sola, il numero di caratteri specificato serve semplicemente come limitatore per non sforare dal buffer. Lì bisogna metterci le dimensioni del buffer di destinazione, non quelle della stringa da copiare.

    Per inciso, poi, strncpy non sarebbe neanche la funzione corretta per questo scopo, dato che era nata inizialmente per le stringhe a lunghezza fissa non necessariamente NUL-terminate come le stringhe in alcune strutture (link), e infatti riempie tutti gli spazi rimanenti con un NUL (inutile per le stringhe C, basta un solo NUL) e soprattutto nel caso in cui la stringa da copiare sia grande come il buffer, non NUL-termina la stringa di destinazione, ed è il motivo per cui spesso si vede roba del tipo
    codice:
    char buffer[255];
    strncpy(buffer,stringa,sizeof(buffer));
    buffer[sizeof(buffer)-1]=0;
    .
    La funzione giusta da utilizzare in questi casi sarebbe la strlcpy, che purtroppo non è standard e non è sempre disponibile; è comunque possibile implementarla in maniera molto semplice (non l'ho provata, ma dovrebbe essere ragionevolmente corretta):
    codice:
    size_t mystrlcpy(char * dest, const char * src, size_t max)
    {
        size_t n;
        for(n=0;*src && n<max; src++, dest++, n++)
            *dest=*src;
        *dest=0;
        return n;
    }
    in alternativa, si può semplicemente azzerare la lunghezza della stringa di destinazione e usare la strncat, che invece funziona in maniera sensata:
    codice:
    char buffer[255];
    /* ... */
    *buffer=0;
    strncat(buffer, stringa, sizeof(buffer));
    .
    Amaro C++, il gusto pieno dell'undefined behavior.

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 © 2025 vBulletin Solutions, Inc. All rights reserved.