[C] Esercizi su selezione/esclusione dati acquisiti da tastiera

U

Utente 125751

Ospite
Ciao :)

Il primo esercizio consiste in:
1)Acquisire da tastiera una lettera, stamparla sullo schermo e determinare se si tratta di
una vocale o di una consonante. Il programma inizierà da capo.
2) Se invece non si acquisisce una singola lettera allora verrà stampato un errore ed il programma ricomincerà da capo.

Per il momento ho fatto questo in Ansi C:

C:
#include <stdio.h>

int main()                         /*4*/

  {
    char let;
    while(1)
    {
      printf("\n\n\t");
      let=getchar();
      if ((let !='\n') || (let !=' '))        /*12*/

         {
            if ((let=='a') || (let=='e')|| (let=='i')|| (let=='o') || (let=='u'))
            printf("\t\n\n%c e' una vocale\n\n",let);
    
            else if ((let=='b') || (let=='c')|| (let=='d') || (let=='f') || (let=='g') || (let=='h') || (let=='j') || (let=='k') || (let=='l') || (let=='m') || (let=='n') || (let=='p') || (let=='r') || (let=='s') || (let=='t') || (let=='v') ||               (let=='w') || (let=='x') || (let=='y') || (let=='z')) 

            printf("\t\n\n%c e' una consonante\n\n",let);
         }
  
      else if ((let=='\n') || (let==' '))  /*22*/
      
          printf("\n\n errore\n\n");   /*24*/

    }

    return 0;

  }

Ho visto ci sono questi warnings:

] Warnings.JPG

Non so se è ok che "il result of comparison is constant"
Non capisco perchè ci sia un "Unreacable code" nella riga 22 ed in quella 24.
Il fatto che sia un infinite loop mi pare ok come cosa. Confermate?

Mi rendo conto ora che devo sostituire la funzione getchar con quella scanf visto che la prima può acquistare solo 1 carattere (char). Creo in aggiunta una variabile di tipo int e la inserisco nella funzione scanf insieme alla variabile let, che è di tipo char.
Pensavo, se ha senso in questo caso, creare una array solo le vocali ed un altro solo per le consonanti.

Poi all' ultimo vorrei migliorare l' efficienza del programma.
 
Ultima modifica da un moderatore:

Spanci03

Utente Attivo
418
87
Periferiche
usb, mouse,tastiera
Net
duckduckgo
OS
windows 7 , debian
Ciao :)

Il primo esercizio consiste in:
1)Acquisire da tastiera una lettera, stamparla sullo schermo e determinare se si tratta di
una vocale o di una consonante. Il programma inizierà da capo.
2) Se invece non si acquisisce una singola lettera allora verrà stampato un errore ed il programma ricomincerà da capo.

Per il momento ho fatto questo in Ansi C:

C:
#include <stdio.h>

int main()                         /*4*/

  {
    char let;
    while(1)
    {
      printf("\n\n\t");
      let=getchar();
      if ((let !='\n') || (let !=' '))        /*12*/

         {
            if ((let=='a') || (let=='e')|| (let=='i')|| (let=='o') || (let=='u'))
            printf("\t\n\n%c e' una vocale\n\n",let);
    
            else if ((let=='b') || (let=='c')|| (let=='d') || (let=='f') || (let=='g') || (let=='h') || (let=='j') || (let=='k') || (let=='l') || (let=='m') || (let=='n') || (let=='p') || (let=='r') || (let=='s') || (let=='t') || (let=='v') ||               (let=='w') || (let=='x') || (let=='y') || (let=='z')) 

            printf("\t\n\n%c e' una consonante\n\n",let);
         }
  
      else if ((let=='\n') || (let==' '))  /*22*/
      
          printf("\n\n errore\n\n");   /*24*/

    }

    return 0;

  }

Ho visto ci sono questi warnings:

[SPOILER
] Visualizza allegato 370135
[/SPOILER]

Non so se è ok che "il result of comparison is constant"
Non capisco perchè ci sia un "Unreacable code" nella riga 22 ed in quella 24.
Il fatto che sia un infinite loop mi pare ok come cosa. Confermate?

Mi rendo conto ora che devo sostituire la funzione getchar con quella scanf visto che la prima può acquistare solo 1 carattere (char). Creo in aggiunta una variabile di tipo int e la inserisco nella funzione scanf insieme alla variabile let, che è di tipo char.
Pensavo, se ha senso in questo caso, creare una array solo le vocali ed un altro solo per le consonanti.

Poi all' ultimo vorrei migliorare l' efficienza del programma.



per quanto riguarda il secondo punto , potresti vedere la lunghezza della stringa , se maggiore di 1 allora stampi l'errore
 
  • Mi piace
Reazioni: Utente 125751

rctimelines

Utente Èlite
5,144
2,023
CPU
Ryzen 7 2700X | i7-6700k@4.5 | i5-4460... altri
Dissipatore
wraith MAX | Scythe Katana2|Arctic Freezer 11LP
Scheda Madre
Asrock B450 Fatal1ty 4K | Asus Prime Z270P | Acer Veriton
HDD
Samsung 970evo m.2 | vari | Samsung 860 evo
RAM
16GB G.Skill TridentZ 3000 | 16GB CORSAIR 2133 | 8GB DDR3 1600
GPU
RadeonPro WX3100 4G | ZOTAC GTX 1070 8G | Quadro k620 2G
Monitor
DELL 2419P 2K + Benq 17" | LG Ultrawide 27''
Net
fibra 1000
OS
Windows10-pro64/OpenSUSE-QL15.1/Debian 10.3
Ma perché fare un loop infinito con "while(1)" che è un uso improprio?

E poi, come logica di programma: una volta individuata se è una vocale, occorre fare tutti quei confronti per stabilire se è una consonante?? Pessima strategia! Lo stesso per l'altra condizione: quando ne poni una, non serve specificate quella alternativa dopo l'else, a meno che non ce ne siano di ulteriori.

Usare degli Array per gli insiemi di lettere e fare la ricerca all'interno di questi sarebbe il minimo sindacale!
Poi c'è anche il problema dei caratteri maiuscoli.. sono vocali o consonanti anche quelle??? E inserendo un numero cosa succede?
Forse è il caso di lavorare sulla codifica dei caratteri?


Inviato dal mio Nexus 6P utilizzando Tapatalk
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,918
11,562
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
almeno momentaneamente, supponi che l'utente inserisca sicuramente una lettera dell'alfabeto e togli l'else if:
se una lettera non è una vocale, allora è per forza una consonante (tieni anche conto che può essere una maiuscola o una minuscola);
in tal caso non c'è bisogno di specificare che se il carattere è b,d,d,..,z allora è una consonante.
Prova a farlo prima in questo modo, senza considerare la possibile immissione di caratteri di punteggiatura o altro.
Poi estendi il programma considerando anche caratteri speciali e/o maiuscole/minuscole: in quel caso ti potrebbe essere comodo confrontare se il numero intero associati all'ASCII del carattere è compreso in un certo intervallo (esclusi i codici numerici delle vocali)

P.S.
tecnicamente qualcuno potrebbe obbiettare che y (soprattutto in inglese) si comporta a volte da consonante e talvolta da vocale, ma non è questo il punto, non ha importanza e lo tralasciamo
 
Ultima modifica:

Spanci03

Utente Attivo
418
87
Periferiche
usb, mouse,tastiera
Net
duckduckgo
OS
windows 7 , debian
Ciao :)

Il primo esercizio consiste in:
1)Acquisire da tastiera una lettera, stamparla sullo schermo e determinare se si tratta di
una vocale o di una consonante. Il programma inizierà da capo.
2) Se invece non si acquisisce una singola lettera allora verrà stampato un errore ed il programma ricomincerà da capo.

Per il momento ho fatto questo in Ansi C:

C:
#include <stdio.h>

int main()                         /*4*/

  {
    char let;
    while(1)
    {
      printf("\n\n\t");
      let=getchar();
      if ((let !='\n') || (let !=' '))        /*12*/

         {
            if ((let=='a') || (let=='e')|| (let=='i')|| (let=='o') || (let=='u'))
            printf("\t\n\n%c e' una vocale\n\n",let);
    
            else if ((let=='b') || (let=='c')|| (let=='d') || (let=='f') || (let=='g') || (let=='h') || (let=='j') || (let=='k') || (let=='l') || (let=='m') || (let=='n') || (let=='p') || (let=='r') || (let=='s') || (let=='t') || (let=='v') ||               (let=='w') || (let=='x') || (let=='y') || (let=='z')) 

            printf("\t\n\n%c e' una consonante\n\n",let);
         }
  
      else if ((let=='\n') || (let==' '))  /*22*/
      
          printf("\n\n errore\n\n");   /*24*/

    }

    return 0;

  }

Ho visto ci sono questi warnings:

[SPOILER
] Visualizza allegato 370135
[/SPOILER]

Non so se è ok che "il result of comparison is constant"
Non capisco perchè ci sia un "Unreacable code" nella riga 22 ed in quella 24.
Il fatto che sia un infinite loop mi pare ok come cosa. Confermate?

Mi rendo conto ora che devo sostituire la funzione getchar con quella scanf visto che la prima può acquistare solo 1 carattere (char). Creo in aggiunta una variabile di tipo int e la inserisco nella funzione scanf insieme alla variabile let, che è di tipo char.
Pensavo, se ha senso in questo caso, creare una array solo le vocali ed un altro solo per le consonanti.

Poi all' ultimo vorrei migliorare l' efficienza del programma.


Comunque ti basta fare un semplice do while per il primo punto per vedere se non è una vocale , e togli tuttte quelle condizioni negli else che non servono a nulla.

per quanto riguarda il secondo punto , potresti vedere la lunghezza della stringa , se maggiore di 1 allora stampi l'errore .
 

BrutPitt

Utente Attivo
1,166
1,262
Per cio' che riguarda i Warnings: il primo ti dice che quella condizione sara' costante, ossia SEMPRE la stessa (in questo caso SEMPRE vera), quindi gli altri sono una conseguenza: ossia il codice (a riga 22 e 24) non sara' MAI raggiungibile, perche' non ci sara' MAI una condizione else

Visto che tutti gli altri ti hanno messo sulla strada per risolvere il punto 1)

Per cio' che riguarda il punto 2):
Attualmente non hai modo di stabilire se e' stato inserito piu' di un carattere alla volta (getchar) ... devi utilizzare un'altra funzione di input.
 

Spanci03

Utente Attivo
418
87
Periferiche
usb, mouse,tastiera
Net
duckduckgo
OS
windows 7 , debian
Per cio' che riguarda i Warnings: il primo ti dice che quella condizione sara' costante, ossia SEMPRE la stessa (in questo caso SEMPRE vera), quindi gli altri sono una conseguenza: ossia il codice (a riga 22 e 24) non sara' MAI raggiungibile, perche' non ci sara' MAI una condizione else

Visto che tutti gli altri ti hanno messo sulla strada per risolvere il punto 1)

Per cio' che riguarda il punto 2):
Attualmente non hai modo di stabilire se e' stato inserito piu' di un carattere alla volta (getchar) ... devi utilizzare un'altra funzione di input.

per quanto riguarda il secondo punto , potresti vedere la lunghezza della stringa , se maggiore di 1 allora stampi l'errore .
Io in c# cosi faccio
 
U

Utente 125751

Ospite
Vi ringranzio intanto per le risposte ed i consigli :)

Ho un po' sistemato correngo errori/warning però ma c'è un errore/ci sono 2 errori identichi e non riesco a venirne fuori:
C:
#include <stdio.h>

int main()

  {
    char voc[10]={'a','e','i','o','u','A','E','I','O','U'};
    char cons[40]= {'b','c','d','f','g','h','j','k','l','m','n','p','r','s','t','v','w','x','y','z','B','C','D','f','G','H','J','K','L','M','N','P','R','S','T','V','W','X','Y','Z'};
    char user;
    int i=0;
    int x=1;
    while (x<2)
    {
     
   
      printf("\n\n\t");
      user=getchar();
     
      if ((user =='\n') || (user ==' '))

         {
           for (i==0;i<1;i++)
           
             {
               if (user==voc[i])
               printf ("\t\n\n%c e' una vocale\n\n",user);

               else (user==cons[i])
               printf("\t\n\n%c e' una consonante\n\n",user);
             }
         
         }
   
      else ((user =='\n') || (user ==' '))  
       
          printf("\n\n errore\n\n");

    }

    return 0;

  }

Errore/errore:

Errori.JPG

Ho provare a fare delle modifiche, a cancellare delle cose ma ma non riesco a risolvere l' errore/i 2 due errori.
Ho provato con un compilatore online C ma stessa storia. Ho controllato di nuovo e per me non ci sono punti in cui ci va questo ";" (senza virgolette . Non riesco a capire cosa che mi sfugge.
Anche con solo l' array delle vocali e senza un confronto su "else": se scrivo una vocale mi stampa ".

per quanto riguarda il secondo punto , potresti vedere la lunghezza della stringa , sia se inseriscono una vocale e sia se invece inserisco una consonante mi stampa anche "e' una consontante" (senza "") e non sono riuscito a risolvere questo problemino anche se ho provato a fare dei tentativi.

Non ci avevo pensato. Mi pare una soluzione valida :)

Ma perché fare un loop infinito con "while(1)" che è un uso improprio?

E poi, come logica di programma: una volta individuata se è una vocale, occorre fare tutti quei confronti per stabilire se è una consonante?? Pessima strategia! Lo stesso per l'altra condizione: quando ne poni una, non serve specificate quella alternativa dopo l'else, a meno che non ce ne siano di ulteriori.

Usare degli Array per gli insiemi di lettere e fare la ricerca all'interno di questi sarebbe il minimo sindacale!
Poi c'è anche il problema dei caratteri maiuscoli.. sono vocali o consonanti anche quelle??? E inserendo un numero cosa succede?
Forse è il caso di lavorare sulla codifica dei caratteri?

Inviato dal mio Nexus 6P utilizzando Tapatalk

Non sono abbastanza informato sui loop infiniti. Per sapere/imparare perchè dici che è un uso improrio? C' entra il fatto che siamo su un computer con in più un s.o. ?
Potrei modificarlo. Ho bisogno che il programma ricominci da capo dopo aver eseguito una delle 3 funzioni printf.

Concordo che ci sono troppi confronti e che bisogna andare su una strategia migliore.
Quando ho scritto questo programmino non conoscevo l' esistenza dei 3 tipi di ricerche in un array.
Aggiungerò le lettere maiuscole. Mi rendo conto che non mi erano venute in mente.
Per i programmi in C uso la codifica ASCII.

almeno momentaneamente, supponi che l'utente inserisca sicuramente una lettera dell'alfabeto e togli l'else if:
se una lettera non è una vocale, allora è per forza una consonante (tieni anche conto che può essere una maiuscola o una minuscola);
in tal caso non c'è bisogno di specificare che se il carattere è b,d,d,..,z allora è una consonante.
Prova a farlo prima in questo modo, senza considerare la possibile immissione di caratteri di punteggiatura o altro.
Poi estendi il programma considerando anche caratteri speciali e/o maiuscole/minuscole: in quel caso ti potrebbe essere comodo confrontare se il numero intero associati all'ASCII del carattere è compreso in un certo intervallo (esclusi i codici numerici delle vocali)

P.S.
tecnicamente qualcuno potrebbe obbiettare che y (soprattutto in inglese) si comporta a volte da consonante e talvolta da vocale, ma non è questo il punto, non ha importanza e lo tralasciamo


Farò quella supposizione per il momento, in modo tale da diminuire la difficoltà dell' esercizio e semplificare il problema da risolvere.

Secondo me:"Se una lettera non è una vocale, allora è per forza una consonante" vale per l' essere umano un minimo istruito o per un programma che sa quante sono in totale le lettere e sa quali, tra di esse, sono le vocali.
Tutti quei confronti vanno tolti. Successivamente mi era venuto in mente che se creo 2 array: "uno per le consonanti e l' altro per le vocali" poi dovrei confrontare ogni elemento dei due array con la singola lettera digitata dall' utente e che questo comporti ad allungare il codice e ad aumentare la dimensione in KB del programma.

Forse potrei anche includere i condici numerici delle vocali insieme alle vocali?
Se non ricordo male in C non è possibile impedire

Mi viene in mente: nel mio programmino linkato nel primo post, ho notato che se non scrivo nulla e premo una volta il tasto invio non viene stampato il messaggio di errore dell' ultimo printf. Stessa cosa succede se premo invece premo una sola volta il tasto space e poi premo invio. Non sono riuscito a capire il perchè di questo comportamente e vorrei saperlo per imparare.
Poi ho fatto un ripasso ed ho capito che ci va else anzichè if else visto che ognuno dei due cicli ha solo due condizioni.

P.S. questa cosa non la sapevo. Se non ha importantanza allora la escludo. Magari in futuro potrebbe essere un altro punto interessante dell' esercizio da fare/risolvere per fini didattici.


Comunque ti basta fare un semplice do while per il primo punto per vedere se non è una vocale , e togli tuttte quelle condizioni negli else che non servono a nulla.

per quanto riguarda il secondo punto , potresti vedere la lunghezza della stringa , se maggiore di 1 allora stampi l'errore .

Provo a fare anche questa opzione con il do-while :)
Per quanto riguarda il secondo punto ( @Bruttpist) pensavo di optare per la funzione scanf. Spero che possa andare bene anche per puro caso non dovesse essere il massimo. Il punto 2) lo farò dopo aver completato il punto 1) perchè necessito di andare per gradi.
 
  • Mi piace
Reazioni: Spanci03

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,222
1,853
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Da quando l'else prevede una condizione? L'else non prevede l'utilizzo di parentesi; il costrutto è if/else oppure if/else-if/else. Devi utilizzare else-if.
Ma come ti è stato fatto notare anche da BAT, è inutile quel controllo: se hai due scelte e ne verifichi una, non può che essere l'altra.

Secondo me:"Se una lettera non è una vocale, allora è per forza una consonante" vale per l' essere umano un minimo istruito o per un programma che sa quante sono in totale le lettere e sa quali, tra di esse, sono le vocali.

Quindi non ha senso questo.
Dovresti inoltre controllare l'input inserito in quanto deve essere una lettera valida: se inserisco un numero viene comunque eseguito, e non è corretto.
Se controlli l'input immesso che sia tra 'a' e 'z' (idem per le maiuscole), ti è sufficiente avere solo l'array delle vocali (visto che sono meno): se il carattere non è in questo array non può che essere una consonante.

E ci sono comunque altri errori, oltre a quello: for (i==0;i<1;i++). Qui non stai assegnando mai stai confrontando.
E comunque non serve un for, viene eseguito solo 1 volta Se vuoi verificare se il carattere inserito sia una vocale, devi scorrere tutto l'array delle vocali (che senso ha fermarsi sempre alla posizione 0?).

Non ho capito nemmeno perchè quell'x < 2... è per "seguire" il consiglio di rct ed evitare il loop infinito? Il "loop infinito" in sè non è sbagliato (magari utilizzando "true" invece di "1"), ci sono contesti nei quali lo si usa. Di solito però si usa una condizione di uscita, settando una variabile booleana.

Sono solo alcuni spunti/considerazioni.
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
ci sono 2 errori identichi e non riesco a venirne fuori:
L'errore è dovuto al fatto che scrivi else con una condizione.
if ((user =='\n') || (user ==' '))
È sbagliato, avrebbe dovuto essere if ((user !='\n') && (user !=' ')), dato che lo scopo è accertarsi che il carattere inserito non sia un newline o uno spazio (= né l'uno né l'altro). E il corrispondente
else ((user =='\n') || (user ==' '))
che, come detto sopra, casomai avrebbe dovuto essere else if ((user =='\n') || (user ==' ')), è ridondante, perché, come ti hanno fatto notare @rctimelines, @BAT00cent e @DispatchCode, se la condizione dell'if risulta falsa, automaticamente risulta vero il suo contrario (in logica booleana a = false implica not_a = true). Quindi bastava scrivere else printf("\n\n errore\n\n");
for (i==0;i<1;i++)
Al netto di quanto fattoti notare da @DispatchCode, si tratta di due vettori di lunghezza diversa, quindi non li puoi visitare con lo stesso indice contemporaneamente.
Per fare una ricerca in un vettore devi scandirlo per intero. Ovviamente ti basta controllare solo uno, e conviene scegliere quello delle vocali (dato che le vocali sono meno delle consonanti). Se il carattere digitato dall'utente non coincide con nessuna vocale, allora sarà per forza una consonante, altrimenti sarà una vocale. Di nuovo,
else (user==cons)
oltre che sbagliato sintatticamente (avrebbe dovuto essere else if), è ridondante, ti basta un semplice else.
Devi riprogettare il ciclo for trasformandolo in un ciclo con flag: inizializzi un flag a 0 (valore arbitrario), scandisci il vettore delle vocali, se il carattere digitato dall'utente è una vocale, poni il flag a 1, esci dal ciclo e stampi che è una vocale. Se tutti i confronti falliscono, vorrà dire che si tratta di una consonante. All'uscita del ciclo il flag sarà ancora a 0 e stamperai che è una consonante.
Non occorre che il vettore delle vocali abbia sia le minuscole che le maiuscole, basta solo un tipo (ad esempio minuscole), e convertire in quello stesso tipo il carattere digitato dall'utente (con le funzioni toupper() e tolower()). Puoi usare la funzione isalpha() per accertarti che si tratti di una lettera.
Puoi usare scanf(" %c", &user); (con lo spazio prima del %) per escludere automaticamente spazi e newline.
 
Ultima modifica:
U

Utente 125751

Ospite
Da quando l'else prevede una condizione? L'else non prevede l'utilizzo di parentesi; il costrutto è if/else oppure if/else-if/else. Devi utilizzare else-if.
Ma come ti è stato fatto notare anche da BAT, è inutile quel controllo: se hai due scelte e ne verifichi una, non può che essere l'altra.

Non avevo capito e non sapevo che fosse un errore mettere una condizione dopo l' else. Non la metto più dopo l' else.
Mi rendo conto di aver pure sbagliato il costrutto nel programmino che ho scritto nel primo messaggio, visto che ho messo else if anzichè else.
Per quanto riguarda l'ultima tua frase: non mi torna quello che hai scritto dopo i ":"

Quando ci sono due scelte pensavo di mettere le condizioni ad entrambe in modo tale da limitare le opzioni o/e di evitare spiacevoli conseguenze visto che non penso sia possibile limitare l' input da tastiera.
Ho capito successivamente che per il ciclo if posso fare: if (condizione) else oppure if (condizione) else if (diversa condizione) else. Poi si possono pure aggiungere più else if (con una condizione diversa).

E ci sono comunque altri errori, oltre a quello: for (i==0;i<1;i++). Qui non stai assegnando mai stai confrontando.
E comunque non serve un for, viene eseguito solo 1 volta Se vuoi verificare se il carattere inserito sia una vocale, devi scorrere tutto l'array delle vocali (che senso ha fermarsi sempre alla posizione 0?).

In effetti andava i=0.
Non sapevo che con il for si potesse fare una ricerca all' interno di uno o più array. Ancora non ho capito l' uso di e come permetta di far funzionare il tutto. Non intendo la "i" del ciclo for.
Non so/sapevo se si ferma/va oppure no ad un certa posizione. Te addirittura mi dici che si ferma alla posizione 0 e poi mi chiedi: "che senso ha?". :boh:
Ho voluto seguire il suggerimento di rct di fare una ricerca negli array. Ho pensato di fare quella lineare mi pareva/pare un po' più semplice. Però a livello di codice non sapevo come si faceva una ricerca in un array. Ho fatto una ricerca su google ed tra varie cose ho trovato il codice di un programma in C (no C++). Lo trovi qui: https://ennebi.solira.org/c-lang/pag22.html

Grazie all' apposito commento ho trovato la parte di codice che, secondo il commento permette di fare la ricerca nell'/negli array. Prima del while ho inizializzato la variabile i e gli ho assegnato il valore 0. Poi ho modificato il ciclo for, addantandolo per mio il programma. Ho provato ed il mio programma per magia faceva la ricerca sia nel primo array, dopo aver digitato una vocale, e sia nel secondo array dopo aver digitato una consonante. Però sia nel primo caso che nel secondo stampava più volte la rispettiva scritta sullo schermo. Ho così diminuito il numero nella seconda espressione del ciclo for e così ho risolto la cosa.

Mi era poi venuto in mente che un modo per fare la ricerca lineare che fosse alla mia portata. Consiste nel confrontare la variabile user con ogni elemento dell' array delle vocali. Poi fare la stessa cosa però con l' array della consonanti.

Quindi non ha senso questo.
Dovresti inoltre controllare l'input inserito in quanto deve essere una lettera valida: se inserisco un numero viene comunque eseguito, e non è corretto.
Se controlli l'input immesso che sia tra 'a' e 'z' (idem per le maiuscole), ti è sufficiente avere solo l'array delle vocali (visto che sono meno): se il carattere non è in questo array non può che essere una consonante.

Facendo una sola verifica, se il dato (in input da tastiera) non è ne una vocale e nemmeno una consonante allora, se non ho capito male, il programma esegue il secondo printf della seconda opzione. Questo io non lo voglio.
Secondo me, se il carattere non è nell' array delle vocali, potrebbe essere una consonante come potrebbe essere un altro tipo di carattere (escluso il '/n' e ' ' ) compreso uno non prensente sulla tastiera ma solo nella tabella ascii. Sbaglio? Se si dove?

Concordo sul controllare l' input inserito. Mi metto al lavoro per trovare una soluzione a questo problemino che mi hai fatto notare :)


Non ho capito nemmeno perchè quell'x < 2... è per "seguire" il consiglio di rct ed evitare il loop infinito? Il "loop infinito" in sè non è sbagliato (magari utilizzando "true" invece di "1"), ci sono contesti nei quali lo si usa. Di solito però si usa una condizione di uscita, settando una variabile booleana.
Si è per seguire il suo consiglio. Mi sembra/va che potesse andare bene però non ci metto la mano sul fuoco. Fammi sapere, per favore.

Per quanto riguarda il "loop infinito": faccio un po' di confusione con l' embedded ed i microcontrollori.
Per sapere/imparare: Perchè true anzichè 1?Se è infinito perchè viene utilizzata la condizione di uscita?
Consulto uno dei libri di testo sperando di trovare qualcosa.

Sono solo alcuni spunti/considerazioni

Ti ringrazio ^^

L'errore è dovuto al fatto che scrivi else con una condizione.

Ho capito. Correggo i due errori.


È sbagliato, avrebbe dovuto essere if ((user !='\n') && (user !=' ')), dato che lo scopo è accertarsi che il carattere inserito non sia un newline o uno spazio (= né l'uno né l'altro). E il corrispondente

Non avevo notato che fosse sbagliato.
Nel secondo programmino era così:
else if ((user !='\n') || (user !=' ')) come avevo scritto nel primo messaggio. Però per cercare di capire l' errore/gli errori di compilazione ho provato varie cose tra cui a cancellare la condizione dall' else e a modificare gli != con gli == nella condizione dell' if.

Come hai scritto tu se almeno una delle due condizioni è vera allora viene eseguito il codice all' interno del ciclo if. Ecco perchè nel primo programminodigitando lo spazio oppure l' invio non succedeva nulla. Lo scopo è quello che hai detto tu solo avevo messo dall' inizio l' operatore logico sbagliato. Corrego il codice.

che, come detto sopra, casomai avrebbe dovuto essere else if ((user =='\n') || (user ==' ')), è ridondante, perché, come ti hanno fatto notare @rctimelines, @BAT00cent e @DispatchCode, se la condizione dell'if risulta falsa, automaticamente risulta vero il suo contrario (in logica booleana a = false implica not_a = true). Quindi bastava scrivere else printf("\n\n errore\n\n");

Poi dopo ho copiato la condizione dell' if e l' ho incollato dopo l' else. Però mi sono dimenticato, nella condizione dell' if, di risostituire gli == con gli != . Mi sono accorto di questa svista solo leggendo il tuo messaggio.
Sarebbere dovuto essere come hai scritto e capisco che è ridondante. Digitando altri caratteri della tastiera non ci saranno effetti indesiderati se per il primo ciclo metto if(condizione da te indicata) else senza mettere quell' istruzione ridondante?
Per il ciclo secondario tolgo la condizione dall' else, perchè è errore. Però ancora non sono convinto che l' aggiunta di un (o forse più di uno) else if (condizione) sia ridondante.


Al netto di quanto fattoti notare da @DispatchCode, si tratta di due vettori di lunghezza diversa, quindi non li puoi visitare con lo stesso indice contemporaneamente.
Per fare una ricerca in un vettore devi scandirlo per intero. Ovviamente ti basta controllare solo uno, e conviene scegliere quello delle vocali (dato che le vocali sono meno delle consonanti). Se il carattere digitato dall'utente non coincide con nessuna vocale, allora sarà per forza una consonante, altrimenti sarà una vocale.

Non conosco l' uso dell' indice dell' array. Non so come faccio a fare la ricerca usando l' indice dell' array.
Con "scandirlo per intero" intendo che bisogna controllare ogni singolo elemento dell' array?
Molto probabilmente potrei riuscire confrontare la variabile user con ogni elemento dell' array.
L' ultima frase non mi torna. Se il carattere digitato dall' utente non coincide con una vocale può essere una consonante come può essere invece un altro carattere oppure un numero etc... Non voglio che venga stampato sullo schermo (... è una consonante) quando non c'è nessuna consonante o/e nessuna vocale.

Di nuovo, oltre che sbagliato sintatticamente (avrebbe dovuto essere else if), è ridondante, ti basta un semplice else.
Non avevo capito che fosse un errore e che avrebbe dovuto essere else if. Per il resto ho risposto sopra.


Devi riprogettare il ciclo for trasformandolo in un ciclo con flag: inizializzi un flag a 0 (valore arbitrario), scandisci il vettore delle vocali, se il carattere digitato dall'utente è una vocale, poni il flag a 1, esci dal ciclo e stampi che è una vocale. Se tutti i confronti falliscono, vorrà dire che si tratta di una consonante. All'uscita del ciclo il flag sarà ancora a 0 e stamperai che è una consonante.
Non occorre che il vettore delle vocali abbia sia le minuscole che le maiuscole, basta solo un tipo (ad esempio minuscole), e convertire in quello stesso tipo il carattere digitato dall'utente (con le funzioni toupper() e tolower()). Puoi usare la funzione isalpha() per accertarti che si tratti di una lettera.
Puoi usare scanf(" %c", &user); (con lo spazio prima del %) per escludere automaticamente spazi e newline.

Non conosco queste cose e sono un po' troppo fuori dalla mia portata. Però prima o poi mi piacerebbe conoscerle e metterle in pratica :)


Puoi usare scanf(" %c", &user); (con lo spazio prima del %) per escludere automaticamente spazi e newline.

Questa cosa, applicata alla funzione scanf, non la sapevo . Come fa uno spazio ad escludere anche un newline?
Per il newline io sapevo che il simbolo è questo \n.
Dentro le due parentesi tonde delle funzione getchar (è solo per 1 carattere) si possono inserire newline o/e spazi?
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Se usi scanf(" %c", &user); vengono ignorati spazi, newline e tab, quindi il controllo della condizione (user !='\n') && (user !=' ') non serve più, a meno che tu non voglia visualizzare un messaggio d'errore apposito.
Digitando altri caratteri della tastiera non ci saranno effetti indesiderati se per il primo ciclo metto if(condizione da te indicata) else senza mettere quell' istruzione ridondante?
Se ti riferisci a if ((user !='\n') && (user !=' ')) (che vuol dire se il carattere non è né newline né spazio), nell'altro ramo ti basta un else, perché se la condizione risulta falsa vuol dire che allora il carattere è certamente o una newline o uno spazio quindi non c'è bisogno di controllare di nuovo (non ci sono altre possibilità).
Per il ciclo secondario tolgo la condizione dall' else, perchè è errore. Però ancora non sono convinto che l' aggiunta di un (o forse più di uno) else if (condizione) sia ridondante.
Se qui ti riferisci a if (user==voc[i]) hai ragione nel dire che se un carattere non è una vocale, non è detto che sia per forza una consonante, dato che potrebbe essere un numero o un segno di punteggiatura, ad esempio. Inizialmente avevo assunto per semplicità di considerare solo caratteri alfabetici, per concentrarci sugli errori più "gravi". Ma poi ho specificato che puoi scremare questa eventualità all'inizio usando la funzione isalpha(), che ti dice se un carattere rappresenta una lettera (accetta maiuscole e minuscole). In questo modo sei certo di operare su caratteri esclusivamente alfabetici.
Un'alternativa potrebbe essere usare un array con tutte le lettere dell'alfabeto, e fare una ricerca all'interno di questo array per sapere se il carattere è alfabetico. Dopodiché potresti memorizzare l'indice del carattere con cui il confronto ha avuto successo e verificare se si tratta di una vocale. Oppure usare un flag che viene avvalorato opportunamente se il carattere con cui il confronto ha avuto successo è una vocale.
Ti basta includere solo le minuscole (ad esempio) nell'array, e convertire preventivamente il carattere digitato in minuscolo con la funzione toupper().
Non conosco l' uso dell' indice dell' array. Non so come faccio a fare la ricerca usando l' indice dell' array.
Con "scandirlo per intero" intendo che bisogna controllare ogni singolo elemento dell' array?
Molto probabilmente potrei riuscire confrontare la variabile user con ogni elemento dell' array.
L' ultima frase non mi torna. Se il carattere digitato dall' utente non coincide con una vocale può essere una consonante come può essere invece un altro carattere oppure un numero etc... Non voglio che venga stampato sullo schermo (... è una consonante) quando non c'è nessuna consonante o/e nessuna vocale.
Semplicemente per scandire un array (o vettore che dir si voglia) devi iterare con un ciclo su tutti i suoi elementi, come hai già fatto nel for, solo che per come avevi posto la condizione veniva visitato solo il primo elemento. Un esempio di ciclo for per visitare un array è
Codice:
for (i = 0; i < SIZE; ++i) {
    // do something;
}
dove SIZE è la dimensione dell'array.
Questo ciclo itera su tutti gli elementi dell'array. Se a te però basta fare una ricerca di un valore, non c'è bisogno di scandire tutto il vettore, ma puoi terminare non appena trovi l'elemento. Allora puoi usare un flag, ossia una variabile "sentinella", che puoi porre a un certo valore quando viene trovato l'elemento. Il loop avrà come condizione che il flag sia diverso da quel valore. Esempio:
Codice:
int flag = 0;
for (i = 0; i < SIZE && flag == 0; ++i) {
    if (user == a[i]) {
        // do something;
        flag = 1; // determina l'uscita dal ciclo
    }
}
Tra l'altro l'uso del flag è mostrato anche nell'esempio di codice che hai linkato.
Questa cosa, applicata alla funzione scanf, non la sapevo . Come fa uno spazio ad escludere anche un newline?
Per il newline io sapevo che il simbolo è questo \n.
Dentro le due parentesi tonde delle funzione getchar (è solo per 1 carattere) si possono inserire newline o/e spazi?
Mettendo lo spazio prima di %c escludi lo spazio, il newline e tab (qui per dettagli su scanf).
getchar() non accetta argomenti (qui il prototipo).
 
Ultima modifica:

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,222
1,853
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Mi ero perso di risponderti, arrivo un pò in ritardo.

Non avevo capito e non sapevo che fosse un errore mettere una condizione dopo l' else. Non la metto più dopo l' else.
Mi rendo conto di aver pure sbagliato il costrutto nel programmino che ho scritto nel primo messaggio, visto che ho messo else if anzichè else.
Per quanto riguarda l'ultima tua frase: non mi torna quello che hai scritto dopo i ":"

Era solo un passaggio logico: se hai due scelte (consonante, vocale) una delle due deve per forza essere vera.
Ma davo un altro consiglio nel post: verificare da subito che il carattere fosse valido

Quando ci sono due scelte pensavo di mettere le condizioni ad entrambe in modo tale da limitare le opzioni o/e di evitare spiacevoli conseguenze visto che non penso sia possibile limitare l' input da tastiera.
Ho capito successivamente che per il ciclo if posso fare: if (condizione) else oppure if (condizione) else if (diversa condizione) else. Poi si possono pure aggiungere più else if (con una condizione diversa).

Rinnovo quanto appena detto. Nel tuo caso sei costretto a valutarle entrambi con if/else-if perchè non verifichi a monte che l'input sia valido.
Si tratta solo di limitare il numero di caratteri consentiti in input.

In effetti andava i=0.
Non sapevo che con il for si potesse fare una ricerca all' interno di uno o più array. Ancora non ho capito l' uso di e come permetta di far funzionare il tutto. Non intendo la "i" del ciclo for.
Non so/sapevo se si ferma/va oppure no ad un certa posizione. Te addirittura mi dici che si ferma alla posizione 0 e poi mi chiedi: "che senso ha?". :boh:
Ho voluto seguire il suggerimento di rct di fare una ricerca negli array. Ho pensato di fare quella lineare mi pareva/pare un po' più semplice. Però a livello di codice non sapevo come si faceva una ricerca in un array. Ho fatto una ricerca su google ed tra varie cose ho trovato il codice di un programma in C (no C++). Lo trovi qui: https://ennebi.solira.org/c-lang/pag22.html

Non ho capito bene che intendi (hai aperto anche un tag BBCode erroneamente).
Io ti dico che si ferma alla posizione 0 semplicemente perchè viene valutata la condizione del ciclo for. Il ciclo viene eseguito sino a che la condizione si verifica (è vera); quindi se inizi con i=0 e come condizione hai i<1.... ovviamente iteri solo 1 volta (che è come non avere il ciclo for).
Per una ricerca lineare molto semplicementi devi scorrere da 0 a N, dove N è il numero di elementi dell'array.

Grazie all' apposito commento ho trovato la parte di codice che, secondo il commento permette di fare la ricerca nell'/negli array. Prima del while ho inizializzato la variabile i e gli ho assegnato il valore 0. Poi ho modificato il ciclo for, addantandolo per mio il programma. Ho provato ed il mio programma per magia faceva la ricerca sia nel primo array, dopo aver digitato una vocale, e sia nel secondo array dopo aver digitato una consonante. Però sia nel primo caso che nel secondo stampava più volte la rispettiva scritta sullo schermo. Ho così diminuito il numero nella seconda espressione del ciclo for e così ho risolto la cosa.

Mi era poi venuto in mente che un modo per fare la ricerca lineare che fosse alla mia portata. Consiste nel confrontare la variabile user con ogni elemento dell' array delle vocali. Poi fare la stessa cosa però con l' array della consonanti.

Come hai modificato il codice? Pubblicalo ora, dopo le variazioni.
In realtà, in un caso come questo, puoi evitare uno degli array (le consonanti, magari). Mi spiego meglio.
Se ti assicuri che in input non ci siano caratteri non validi, visto l'utilizzo che ne fai degli array, puoi anche usare solo quello delle vocali (che sono meno, solo 5).
In questo modo andresti a scorrere l'array delle vocali e se il carattere è presente, è una vocale; se non è presente è una consonante.

Facendo una sola verifica, se il dato (in input da tastiera) non è ne una vocale e nemmeno una consonante allora, se non ho capito male, il programma esegue il secondo printf della seconda opzione. Questo io non lo voglio.
Secondo me, se il carattere non è nell' array delle vocali, potrebbe essere una consonante come potrebbe essere un altro tipo di carattere (escluso il '/n' e ' ' ) compreso uno non prensente sulla tastiera ma solo nella tabella ascii. Sbaglio? Se si dove?


Vale quanto esposto sopra.

Si è per seguire il suo consiglio. Mi sembra/va che potesse andare bene però non ci metto la mano sul fuoco. Fammi sapere, per favore.

Per quanto riguarda il "loop infinito": faccio un po' di confusione con l' embedded ed i microcontrollori.
Per sapere/imparare: Perchè true anzichè 1?Se è infinito perchè viene utilizzata la condizione di uscita?
Consulto uno dei libri di testo sperando di trovare qualcosa.

Fatto così funziona, ma non è corretto... anzi, crea ancora più confusione di prima, poichè non si capisce il significato!
Io quando devo ciclare all'infinito uso while(true); non è errato, ci sono casi nei quali viene utilizzato.
Nel tuo caso puoi ad esempio creare un piccolo menu, dove come opzione dai anche l'uscita, ad esempio.
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!