Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2010
    Messaggi
    99

    [C]strano problema con '%n' nel printf

    ciao a tutti, sto riscontrando uno stranissimo problema quando cerco di usare l'indicatore di conversione %n nel printf, ecco qua il codice:
    codice:
     #include<stdio.h>
    int main(void)
    {
    	int *n;
    	char *x;
    	gets(x);
    	printf("\n%s%n\n",x,&n);
    	printf("n: %d\n",n);
    	return 0;
    }
    ed ecco l'output:
    codice:
    ciao come stai
    
    ciao come stain: -41807480
    
    --------------------------------
    Process exited with return value 0
    Press any key to continue . . .
    ho provato con più codici diversi, anche quello che ho come esempio nel libro, e non va nemmeno quello!!! a questo punto sia problema del mio compilatore uso DevCpp 5.3.0.4 su Win7
    qualche consiglio su cosa potrei fare? thanks in advance

  2. #2
    In dieci righe condensi un numero considerevole di errori grossi come una casa:
    codice:
        char *x;
        gets(x);
    qui non inizializzi x e non allochi nessuna memoria per la stringa che vai a leggere da tastiera, per cui gets va a scrivere in una locazione di memoria più o meno casuale; il fatto che il tuo programma non vada in crash già qui è per pura fortuna.
    Inoltre, gets è deprecata dato che espone a rischio di buffer overflow. Al suo posto usa fgets, specificando le dimensioni del buffer di input.
    codice:
        int *n;
        printf("\n%s%n\n",x,&n);
    A printf, che si aspetta un puntatore ad int (ovvero, la locazione in cui dovrà andare a memorizzare il numero di caratteri stampati), passi un puntatore doppio ad int (int **), per cui va a scrivere questi dati, invece che in un intero, nella locazione di memoria di n (che è un puntatore). Alla riga successiva, poi, passi un puntatore ad intero quando la printf si aspetta un intero.
    Insomma, un pasticcio dall'inizio alla fine.

    Devi:
    - evitare la gets e usare fgets;
    - fornirle un buffer di dimensioni adeguate;
    - dichiarare n come int;
    - studiarti per bene stringhe e puntatori sul tuo libro di C!
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    Apr 2010
    Messaggi
    99
    si scusami avevo incollato un codice vecchio che avevo corretto più tardi, comunque non funziona lo stesso, nemmeno con questo più banale:
    codice:
    #include<stdio.h>
    int main(void)
    {
    	int n;
    	printf("ciao%n\n",&n);
    	printf("%d\n",n);
    	return 0;
    }
    mi scrive
    codice:
    ciao0

    il punto è che su linux funziona alla perfezione!

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Anche su Windows, con altri compilatori ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Dunque.

    Dev-C++ (come molti altri IDE free su Windows) usa come compilatore il gcc fornito da MinGW, che non usa come runtime la glibc che si usa normalmente su Linux, ma "libmsvcrt", una libreria che per il grosso del lavoro richiama msvcrt.dll, il runtime C Microsoft incluso in Windows ma non direttamente supportato dalle versioni di Visual Studio recenti e che per certi versi come funzionalità è fermo a VC++ 6. Credo quindi che per questo motivo la printf non supporti correttamente lo specificatore %n (che invece è supportato nelle versioni più recenti della CRT Microsoft).

    Long story short: non credo ci sia un modo semplice per "aggiustarlo" in generale; per fare una controprova, prova ad usare, invece di printf, __mingw_printf (che chiama la versione C99/POSIX compliant di printf fornita dalla CRT di MinGW). Se funziona correttamente, il problema è lì. libmsvcrt supporta un'opzione di compilazione per impostare le "sue" versioni delle funzioni di libreria come default (vedi qui), ma te la devi ricompilare da te.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,462
    Io ho usato devc++ 4.9 su windows ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it
    Registrato dal
    Apr 2010
    Messaggi
    99
    Originariamente inviato da MItaly
    ...
    Long story short: non credo ci sia un modo semplice per "aggiustarlo" in generale; per fare una controprova, prova ad usare, invece di printf, __mingw_printf (che chiama la versione C99/POSIX compliant di printf fornita dalla CRT di MinGW). Se funziona correttamente, il problema è lì.
    ...
    si il problema era lì grazie mille! ho provato con __mingw_printf e funziona! quindi o uso questa funzione qui oppure cambio compilatore in sostanza?

  8. #8
    Originariamente inviato da oregon
    Io ho usato devc++ 4.9 su windows ...
    Hm, DevC++ 4.9 include MinGW 3.4.2, forse ai tempi (2005 minimo ) usavano la loro implementazione di printf di default... d'altra parte non riesco a trovare in giro i sorgenti in questione, quindi è difficile dire...
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Originariamente inviato da glukosio
    si il problema era lì grazie mille! ho provato con __mingw_printf e funziona! quindi o uso questa funzione qui oppure cambio compilatore in sostanza?
    Puoi seguire i consigli specificati qui (per un altro problema che però ha la stessa motivazione); nello specifico, prima di includere <stdio.h> piazza una #define __USE_MINGW_ANSI_STDIO 1.
    Nota che volendo puoi definire quella macro anche direttamente nelle opzioni del progetto, in modo da evitare di riempire i sorgenti con direttive specifiche per MinGW (l'opzione da linea di comando da specificare sarebbe -D__USE_MINGW_ANSI_STDIO=1).
    Amaro C++, il gusto pieno dell'undefined behavior.

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2010
    Messaggi
    99
    ok grazie mille, ho impostato la macro in devcpp, ora funziona bene
    ho anche aggiornato il compilatore passando dalla TDM-GCC x64 4.6.1 alla 4.7.1 ma i problemi rimanevano, ora invece ho risolto
    grazie ancora e buona serata!

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.