Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 17
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    [C++] strncpy()

    Ciao ragazzi.... il mio problema probabilmente è stupido.... ma purtoppo ce l'ho xD

    devo assgnare il contenuto di un TCHAR * inizializzato con new char [500]
    a un altro TCHAR * con la medesima inizializzazione
    codice:
    TCHAR * sz2;
    sz2 = new char [500];
    sz2 = "";
    strcat(sz2,"ciao");
    TCHAR * sz1;
    sz1 =  new char [500];
    strncpy(sz1,sz2,(strlen(sz2)));
    MessageBox(NULL,sz1,"Errore!!! è stato assegnato il valroe ma comunque ci sono ancora gli spazi del new char [500] colmati con un bel ìììììììììììììììììììììììììììììììììì....etc di default..... come posso risolvere.... lol",0);
    //l'output dovrebbe essere "ciao", ma invece è ciaoìììììììììììììììììììììììììììììììììììììììììììììììììììììììììììììììì etc....
    //o comunque una cosa del genere....
    Aiuto.....

    PS... dovrei scrivere new TCHAR [500] per caso....

  2. #2
    Che pasticcio...

    Come spiegato di là, non puoi assegnare a sz2 il valore "" in quella maniera; devi usare _tcscpy (l'equivalente TCHAR di strcpy), oppure semplicemente azzerare il primo byte della stringa
    codice:
    *sz2=0;
    Inoltre stai usando strcat invece di _tcscat: che senso ha usare la versione a char invece di quella per TCHAR? Lo stesso vale per la strncpy usata poco dopo. E perché allochi un array di char e poi lo assegni ad un puntatore a TCHAR? Dovresti allocare direttamente una stringa di TCHAR.
    Inoltre, la strlen nella strncpy non ha nessun senso: strncpy si occupa autonomamente di calcolare quanti caratteri ci sono da copiare dalla stringa di partenza; piuttosto si usa strncpy per evitare di copiare più caratteri di quanti ne possa contenere la stringa di destinazione.
    La cosa più sensata di tutte, poi, sarebbe lasciar stare strcat e _tcscat, e usare direttamente _tcsncpy per copiare la stringa nel buffer.
    Infine, devi sempre ricordarti di deallocare la memoria allocata con new, e di gestire l'eventuale eccezione di allocazione che si può verificare.
    codice:
    TCHAR * sz2=NULL, * sz1=NULL;
    try
    {
        sz2 = new TCHAR [500];
        _tcscpy(sz2,"ciao");
        sz1 =  new TCHAR [500];
        _tcsncpy(sz1,sz2,500);
        MessageBox(NULL,sz1,"L'abuso di LOL deve morire",0);
    }
    catch(std::bad_alloc & ex)
    {
        MessageBox(NULL, "Impossibile allocare la memoria necessaria", "Errore", MB_ICONERROR);
    }
    delete [] sz2;
    delete [] sz1;
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    Capisco

    Cavolo che roba.... capisco.... comunque io volevo assegnare a sz1 solo tutti i caratteri di sz2 - 1 (cioè "cia").... e un'altra cosa.... ma adesso se stampo sz1 non mi venire fuori ciaoìììììììììì etc..etc... oppure è aggiunto automaticamente un bel 0x00 alla fine della stringa.....?

    ps.: cos'hai contro l'abuso di LoL ?

  4. #4

    Re: Capisco

    Originariamente inviato da kirakira93
    Cavolo che roba.... capisco.... comunque io volevo assegnare a sz1 solo tutti i caratteri di sz2 - 1 (cioè "cia")....
    In tal caso sarebbe dovuto essere min(_tcslen(sz2)-1, 500).
    e un'altra cosa.... ma adesso se stampo sz1 non mi venire fuori ciaoìììììììììì etc..etc... oppure è aggiunto automaticamente un bel 0x00 alla fine della stringa.....?
    Le varie funzioni di manipolazione delle stringhe aggiungono automaticamente il NUL a fine stringa (tranne alcune, come la strncpy, che, se la copia raggiunge il numero massimo di caratteri specificato, non aggiunge il NUL, e infatti mi sono dimenticato di fare l'aggiunta manuale di sicurezza nel codice che ho postato).
    ps.: cos'hai contro l'abuso di LoL ?
    Lo stesso che ho contro le k e l'abuso di xD.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    capito!

    ok ho capito.... ma come faccio a sapere la dimensione di sz2.... cioè con sizeof(sz2) non me la ricava perchè è un TCHAR * e non un TCHAR[].....
    e poi un'altra cosa.... per aggiungere il \0 a fine stringa uso _tcscat(sz1,"\0")..... ma non penso che sia un buon metodo..... arg.... sono impacciato....

  6. #6

    Re: capito!

    Originariamente inviato da kirakira93
    ok ho capito.... ma come faccio a sapere la dimensione di sz2.... cioè con sizeof(sz2) non me la ricava perchè è un TCHAR * e non un TCHAR[].....
    Tu hai allocato l'array, tu sai quanto è grande. D'altronde è noto che queste stringhe sono piuttosto odiose, e in C++ si usa basic_string (e le sue specializzazioni per i vari tipi di char) per maneggiare le stringhe.
    e poi un'altra cosa.... per aggiungere il \0 a fine stringa uso _tcscat(sz1,"\0")..... ma non penso che sia un buon metodo..... arg.... sono impacciato....
    _tcscat cerca prima di tutto la fine della stringa, e per cercarla cerca un NUL. In pratica, si aspetta una stringa già NUL-terminata, per cui non lo puoi usare per aggiungere il NUL finale.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    giusto...

    esatto.... ho scitto una cavolata..... basta fare sz1[iGrandezzaDisz2] '\0'.....
    ma a questo punto mi viene un dubbio..... non bastava fare così:

    codice:
    TCHAR * sz2=NULL, * sz1=NULL;
    try
    {
        sz2 = new TCHAR [500];
        _tcscpy(sz2,"ciao");
        sz1 =  new TCHAR [500];
        _tcsncpy(sz1,sz2,500);
        sz1[_tcslen(sz2) - 1] = '\0';
        /*lo strlen() per il TCHAR adesso non ricordo.... mi pare _tcslen()*/
        MessageBox(NULL,sz1,"In questo caso un LoL ci sta propio a pallino!",0);
    }
    catch(std::bad_alloc & ex)
    {
        MessageBox(NULL, "Impossibile allocare la memoria necessaria", "Errore", MB_ICONERROR);
    }
    delete [] sz2;
    delete [] sz1;
    E anche l'xD ci sta bene.... bisogna scrivere _tcsncpy(sz1,sz2,500); non _tcsncpy(sz1 - 1,sz2,500);..... xD anche se non ho capito bene cosa fa sz1 - 1

    .... comunque grazie di tutto..... ora torno a fare le mie equazioni di 2° grado per domani....

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    un'altra cosa

    un ultima cosa.... volevo chiederti se mi potevi spiegare il std::bad_alloc & ex....
    facendo il debug col vs 2010 prima di crashare nel calore della variabile c'era scritto bad_alloc... quindi intuitivamente penso che sia un messaggio che viene inviato a windows e se si verifica gestisce l'eccezzione facendo tanto odiosamente crashare il programma.... invece con il try catch (...) il messaggio viene gestito....
    o azzeccato almeno qualcosa?
    e poi non ho capito un'altra cosa: & ex.... perchè?

  9. #9

    Re: giusto...

    Originariamente inviato da kirakira93
    esatto.... ho scitto una cavolata..... basta fare sz1[iGrandezzaDisz2] '\0'.....
    ma a questo punto mi viene un dubbio..... non bastava fare così:

    codice:
    TCHAR * sz2=NULL, * sz1=NULL;
    try
    {
        sz2 = new TCHAR [500];
        _tcscpy(sz2,"ciao");
        sz1 =  new TCHAR [500];
        _tcsncpy(sz1,sz2,500);
        sz1[_tcslen(sz2) - 1] = '\0';
        /*lo strlen() per il TCHAR adesso non ricordo.... mi pare _tcslen()*/
        MessageBox(NULL,sz1,"In questo caso un LoL ci sta propio a pallino!",0);
    }
    catch(std::bad_alloc & ex)
    {
        MessageBox(NULL, "Impossibile allocare la memoria necessaria", "Errore", MB_ICONERROR);
    }
    delete [] sz2;
    delete [] sz1;
    E anche l'xD ci sta bene.... bisogna scrivere _tcsncpy(sz1,sz2,500); non _tcsncpy(sz1 - 1,sz2,500);..... xD anche se non ho capito bene cosa fa sz1 - 1
    Non ci siamo capiti... il sz1[/* bla bla bla*/]='\0'; serve per terminare la stringa qualora già non fosse terminata; e proprio in questo caso la _tcslen non sarebbe in grado di determinare quando la stringa finisce, proprio perché il terminatore finale sarebbe assente.
    Comunque basta aggiungere un '\0' di precauzione sull'ultimo carattere allocato del buffer, in maniera tale da terminare lì con sicurezza la stringa.
    codice:
    sz1[499]=0;
    .... comunque grazie di tutto..... ora torno a fare le mie equazioni di 2° grado per domani....
    Divertiti.
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    ok

    allora non mi è chiara una cosa....
    se io metto \0 all'ultimo elemento del vettore: [499] la stringa viene considerata di 499 caratteri.... ma io passo come parametro della _tsclen() sz2 di cui so la grandezza perchè è stato assegnato "ciao" (e quindi anche NUL).... oppure ho sbagliato q capire qualcosa...

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.