PROBLEMA Il mio programma C non acquisisce il tipo char per l'esecuzione dello switch case

ZuTure

Nuovo Utente
9
0
C:
#include <stdio.h>


struct paolo

{

    float reali;

    float immagginari;

};

typedef struct paolo num_complessi;




main()

{

    num_complessi n, n1;

    float som, somma, molti, i, j;

    char scelta;

    printf("Inserisci il primo numero complesso: \n");

    scanf("%f", &n.reali);                                        //acquisizione numeri complessi in coppia per la configurazione di a+jb

    scanf("%f", &n.immagginari);

    printf("Inserisci il secondo numero complesso: \n");

    scanf("%f", &n1.reali);

    scanf("%f", &n1.immagginari);

    printf("\nI numeri complessi inseriti sono: %f + j%f e %f + j%f \n\n", n.reali, n.immagginari, n1.reali, n1.immagginari);

    do{

      

//da qui

        printf("addizzione(a), sottrazione(s), prodotto(p) o divisione(d):  ");

        scanf("%c", &scelta);

   //a qui non esegue la scanf

        switch (scelta)            //scelta dell'operazione da effettuare

        {

            case 'a':

            som = n.reali + n1.reali;

            somma = n.immagginari + n1.immagginari;

            printf("La somma dei numeri complessi è: %f + j%f \n\n", som, somma);        //somma della coppia di numeri complessi in due variabili per la configurazione di a+jb

            break;

          

            case 's':   

            som = n.reali - n1.reali;

            somma = n.immagginari - n1.immagginari;

            printf("La differenza tra i numeri complessi e': %f + j%f\n\n", som, somma);        //differenza della coppia di numeri complessi in coppia per la configurazione di a-jb

            break;

      

            case 'p':

            som = n.reali * n1.reali - n.immagginari * n1.immagginari;

            somma = n.reali * n1.immagginari + n1.reali * n.immagginari;

            printf("La moltiplicazione è: %f + j%f\n\n", som, somma);    //moltiplica reale*reale1 - immaginario*immaginario1  e  reale*immaginario1 + reale1*immaginario

            break;

      

            case 'd':

            i = n1.reali * n1.reali - n1.immagginari * n1.immagginari;

            som = (n.reali * n1.reali - n1.immagginari * n.immagginari) / i;        //divisione tra a+jb e a1+jb1

            somma = (n1.reali * n.immagginari - n.reali * n1.immagginari) / i;

            printf("La divisione è %f - j%f", som, somma);

            break;

          

            default:

            printf("Scelta non valida\n\n");

            j = 0;

        }

      

        printf("Vuoi effettuare altre operazione? y/n: ");

        scanf("%c", &scelta);

        if(scelta == 'y')

        {

            j = 0;

        }   

        else

        {

            j = 1;

        }

    }while(j == 0);

  

}

Sono uno studente e questo programma grazie all'utilizzo delle strutture serve ad effettuare varie operazioni con i numeri complessi, le operazioni sono perfettamente funzionanti (dovrebbero) ma non riesco a capire perchè non funziona lo switch case e la scanf con tipo char scelta.
 

Allegati

  • immagine_2022-04-16_113713976.png
    immagine_2022-04-16_113713976.png
    49.5 KB · Visualizzazioni: 31
Ultima modifica da un moderatore:

BAT

Moderatore
Staff Forum
Utente Èlite
22,941
11,577
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
cortesemente la prossima volta usa il TAG per il codice nell'inserire il listato di un programma, questa volta lo faccio io;
qualche suggerimento di carattere generale:
  • nel denominare le variabili/funzioni è buona norma dare nomi significativi: una struct che si chiama paolo difficilmente è associabile a un numero complesso...
  • un po' di attenzione alla grammatica: gli esercizi sono presumibilmente revisionati da un docente, che quando vede scritto nel codice immagginari oppure addizzione potrebbe partire prevenuto ?
  • credo di avrlo detto già molte volte, ma lo ripeto di nuovo l'intestazione corretta del main in C è
C:
int main(void){
    // bla bla bla
    ...
    return 0; // restituisce il "successo"
}
 

Andretti60

Utente Èlite
6,440
5,091
Il problema dello scanf() con il formato “%c” è che viene letto un carattere nel buffer di ingresso, dove solitamente rimane il newline dell’istruzione scanf() precedente. La maniera più semplice per evitare ciò è leggere una stringa di caratteri (usando quindi il %s) e usare poi il primo carattere di tale stringa. Non elegante, ma funziona (il linguaggio C è pieno di questi piccoli problemi).
A parte quello suggerito da @BAT riguardo la scelta dei nomi e gli errori ortografici, ti suggerisco di usare il formato double invece del float, che ha grossi problemi di arrotondamento.


  • credo di avrlo detto già molte volte, ma lo ripeto di nuovo l'intestazione corretta del main in C è
In realtà non è vero, il main() accetta più intestazioni, se il valore di ritorno non viene utilizzato (come in questo caso) si può benissimo usare void main()
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,941
11,577
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
il main() accetta più intestazioni
ho dato la "forma canonica" più semplice (a zero paramentri) che prevede di restituire un int
a seconda del compilatore anche senza inserire esplicitamente il return finale viene restituito un valore (int) di successo
l'altra "forma canonica" standard che accetta parametri in input è
C:
int main(int argc, char *argv[]) {
   // bla bla bla
}
il fatto che i compilatori C ti accettano praticamente tutto ciè che ti passa per la testa come main, non significa che ciò sia corretto né dal punto di vista formale del C standard e neppure dal punta di vista pratico in quanto restituire un void potrebbe dar luogo ad un comportamento indefinito (o se preferisci un "undefined behaviour"), i cui effetti non possono ovviamente essere evidenti in un programma scolastico.
Quindi perché incoraggiare cattive abitudini? esiste uno standard, meglio seguirlo no?
 

Andretti60

Utente Èlite
6,440
5,091
Il problema è che in C non esiste standard alcuno. Usando lo stesso criterio potrei contestare che il prototipo dovrebbe essere
Main(int argc, char **argv, char **envp)
Ma non ha senso se tali valori non vengono utilizzati.
Al contrario, se il valore di ritorno NON viene utilizzato (come avviene per molti casi, come in questo) mettere un valore di ritorno sia considerato “bad code” in quanto inserisce una istruzione inutile e che potenzialmente potrebbe causare confusione a chi legge il code.
 

ZuTure

Nuovo Utente
9
0
Il problema dello scanf() con il formato “%c” è che viene letto un carattere nel buffer di ingresso, dove solitamente rimane il newline dell’istruzione scanf() precedente. La maniera più semplice per evitare ciò è leggere una stringa di caratteri (usando quindi il %s) e usare poi il primo carattere di tale stringa. Non elegante, ma funziona (il linguaggio C è pieno di questi piccoli problemi).
A parte quello suggerito da @BAT riguardo la scelta dei nomi e gli errori ortografici, ti suggerisco di usare il formato double invece del float, che ha grossi problemi di arrotondamento.



In realtà non è vero, il main() accetta più intestazioni, se il valore di ritorno non viene utilizzato (come in questo caso) si può benissimo usare void main()
grazie mille provvederò a provare il tutto
 

giammo82

Utente Attivo
1,209
525
Io all’inizio quando scrivevo i primi programmi in C utilizzavo il doppio scanf() perché sapevo che il primo veniva ignorato per il buffer, poi son passato ad utilizzare il getchar ()


Inviato dal mio iPhone utilizzando Toms Hardware Italia Forum
 
  • Mi piace
Reazioni: bigendian e BAT

bigendian

Utente Attivo
748
431
OS
Linux
alle universita' piace scanf(), :)
Nel caso, per risolvere quanto ricordato dall'amico andretti,

Codice:
scanf(" %c", &scelta);

ma anche a mio avviso getchar() piu intuitivo/semplice
 
Ultima modifica:

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!