Errore strano nella stampa a terminale

di il
11 risposte

Errore strano nella stampa a terminale

Ciao a tutti, dopo una lunga scelta ho deciso di cimentarmi col C++ per programmare un software e così, anche se conosco un po' del C++ (anche se non puro perché uso un IDE che trae dal C++).

Ho però un errore che reputo strano con questo codice:
/*
 * Semplice programma §che mostra come utilizzare char
 * sia come contenitore di caratteri che come
 * contenitore di valori numerici interi
 */
#include <iostream>
int main()
{
    char carattere;
    char numero;
    
    printf("Inserire un carattere a scelta e premere INVIO: ");
    scanf("%c", &carattere);
    
    printf("Inserire un intero compreso tra 0 e 127: ");
    scanf("%d", &numero);
    
    printf("Il carattere inserito è: %c\n", carattere);
    printf("Il numero inserito è: %d\n", numero);
    
    return(0);
}
Che a video stampa bene frasi e numero, ma non stampa il carattere...
Il terminale mi da un warning in fase di compilazione, ma parla dell'unica cosa che funziona:
main.cpp:16:17: warning: format specifies type 'int *' but the argument has type
      'char *' [-Wformat]
    scanf("%d", &numero);
           ~~   ^~~~~~~
           %s
1 warning generated.

11 Risposte

  • Re: Errore strano nella stampa a terminale

    Se è un numero intero deve essere

    int numero;

    e non

    char numero;
  • Re: Errore strano nella stampa a terminale

    Mi permetto di dissentire, nel senso char è una variabile a 8 bit, poco gli interessa a lui se è un carattere o un numero. Lo stesso carattere in ASCII corrisponde a un numero...
    Tra l'altro, come detto, il numero lo stampa corretto, è il carattere (lettera) che crea problemi
  • Re: Errore strano nella stampa a terminale

    Quello che viene evidenziato è un "warning" quindi un avvertimento non un errore.

    Viene espressamente segnalata la linea

    scanf("%d", &numero);

    e viene indicato

    format specifies type 'int *' but the argument has type 'char *'

    che mi sembra chiarissimo.

    Quindi tu puoi dissentire quanto vuoi e puoi utilizzare char al posto di int ma il compilatore continuerà a darti quel warning comunque.

    Usare %d e un char può creare problemi.
    è il carattere (lettera) che crea problemi
    Cioè? Che problemi?
  • Re: Errore strano nella stampa a terminale

    Appunto da un warning perché un int sarebbe un carattere a 2byte. Ma non che char non può essere un numero. Solo che può essere un 8 bit. quindi -128/127 o 0/255 se unsigned.
    Ora o non conosco, o non è previsto, l'identificatore %... Per i numeri short oppure devo usare %s forse...(che ho provato ma funziona ancora peggio nel senso che sballa il numero)
    Ad ogni modo il problema non sta li, nel senso che mi rendo conto non sia la forma più corretta per scriverlo, ma funziona, nel senso che char è i 8bit e gli 8 bit puoi occuparli come vuoi

    Comunque mi da problemi nel senso che non stampa il carattere come indicato nel primo post.
  • Re: Errore strano nella stampa a terminale

    A meno che tu non lavori con un sistema a 16 bit, un intero è a 32 bit.

    Quindi se usi %d e un char succede che per il valore inserito, anche se più piccolo di 128, sono utilizzate dalla scanf 4 locazioni di memoria. Dato che hai preparato solamente due locazioni nello stack per i due char, la scanf dell'intero sovrascrive l'area utilizzata dal char inserito in precedenza.

    Per spiegarmi meglio, se inserisci A per il primo input, viene scritto

    65

    nella variabile carattere e se scrivi 96 per il secondo input, viene scritto

    96 0 0 0

    a partire dalla variabile numero. Il primo 0 sovrascrive la variabile carattere e tu non vedi più quello che hai inserito. In più gli altri due 0 sporcano lo stack e possono anche causare problemi di seg fault.

    Ecco perché è importante quel warning.
  • Re: Errore strano nella stampa a terminale

    Hai ragione ho sempre usato C++ per arduino che lavora a 16 bit, ma il concetto è quello, cioè un char può contenere un numero seppur limitato al suo spazio. Questo intendevo dire.

    Per quanto riguarda l'errore non capisco bene, evidentemente non conosco il ragionamento di scanf che nella guida che sto seguendo non è usato (e su arduino lavorando su input di seriali o altri protocolli di comunicazione non uso)
    Se non ho capito male lavora un po' come coi registri:
    Io preparo 4 byte (2 char) ma siccome scanf ne vuole 4 ogni volta che scrive lui inizia a scrivere dove gli indico (quindi nella prima chiamata copre il primo slot) e poi va avanti fino a che non finisce. La seconda chiamata fa si che venga occupato il primo slot del secondo char, ma avendo bisogno di 4 slot passa a quello successivo e poi finisce a sovrascrivere i due slot precedenti, corretto?

    Forse sono stato un po contorto...scusami
  • Re: Errore strano nella stampa a terminale

    Probabilmente hai compreso il problema ma quello che hai scritto è abbastanza contorto ...

    Intanto cominci con "Io preparo 4 byte (2 char)" ma in realtà tu prepari 2 byte (2 char) ... e poi mi sono perso ...

    In memoria (nello stack) è previsto spazio per 2 char, il primo lo chiamiamo n (numero) e il secondo c (carattere), supponendo che contengano 0 all'inizio avremo

    n c
    0 0

    quando fai l'input, ad esempio di A per il carattere, in memoria viene scritto

    n c
    0 65

    ma quando fai l'input del numero, ad esempio 96, dato che vengono utilizzati 4 byte dalla %d della scanf, in memoria avrai

    n c
    96 0 0 0

    e quindi perdi il 65. La printf seguente non visualizzerà nulla.

    Anche se il sistema con cui lavori utilizza un valore a 16 bit per il numero, avrai

    n c
    96 0

    e quindi il discorso vale comunque.
  • Re: Errore strano nella stampa a terminale

    scanf("%hhd",&numero);
  • Re: Errore strano nella stampa a terminale

    Grazie mille, mi sono ingannato sui quattro valori, ma intendevo quello che dicevi tu, perfetto!
    Grazie, davvero gentilissimo
  • Re: Errore strano nella stampa a terminale

    vbextreme ha scritto:


    scanf("%hhd",&numero);
    Non è uno switch utilizzabile da tutti i compilatori. Non per Visual C++ ad esempio.

    Non è consigliabile usarlo, meglio un input con un intero temporaneo e in seguito estrarne la parte bassa.
  • Re: Errore strano nella stampa a terminale

    Vi rompo ancora, dove trovo una guida fatta bene sul C++? Perché quella su HTML.it non so se sia vecchia o cosa, ma ha problemi dappertutto, dall'assenza della dichiarazione del type prima del main, a quello che abbiamo visto prima, a una serie di errori e warning sull'uso di cout...
Devi accedere o registrarti per scrivere nel forum
11 risposte