PDA

View Full Version : [C] Programma con o senza vocali/consonanti


Cadetto Entusiasta
10-12-2009, 16:26
Buongiorno/Buonasera! Ho da svolgere due esercizi molto similari tra loro. In parole povere, nel primo devo far in modo che il programma restituisca il testo inserito dall'utente, senza le vocali; il secondo, è il contrario, cioè che mi restituisca solo le vocali e non le consonanti.
Io son già riuscito a far in modo che il programma restituisca tutto il testo che gli inserisco, però da qui in avanti non so che fare



#include <stdio.h>
#define MAXBC 123

int main()
{
char buf[MAXBC];
int i, xc;

for( i = 0; (i < (MAXBC+1)) && ((xc = getchar()) != EOF) && (ch != '\n'); i++ )
buf[i] = (char)xc;

buf[i] = '\0';
printf( "%s\n", buf );

return 0;
}



Pensato di fare un controllo nel for così
if (tolower(xc) == 'a')
però poi non so cosa fare per non farla riscrivere...
Gentilmente qualcuno può aiutarmi?

Cadetto Entusiasta
10-12-2009, 16:54
Nel mentre ho trovato anche questa soluzione per leggere tutti i caratteri con getchar e putchar



#include <stdio.h>

int main()
{
int xc;

while ((xc=getchar()) != EOF)
{
putchar(xc);
}

return 0;
}



ma comunque non so come andare avanti

blackgin
10-12-2009, 17:46
Potresti creare un array con le vocali. Quindi inserire un ciclo for che controlla se cio' che ottieni con il getchar() e' o no contenuto nell'array (quindi controlla se e' una vocale).

Cadetto Entusiasta
12-12-2009, 09:28
Scusami, ma potresti spiegarmi cosa intendi?

blackgin
12-12-2009, 10:04
Ottieni il carattere con getchar(). Quindi lo vai a mettere in un for che lo confronta ad uno ad uno coi vari elementi dell'array contenente a, e, i, o, u. Quindi restituisce il carattere solo se e' diverso da questi elementi

Cadetto Entusiasta
12-12-2009, 10:29
Ok, però come si farebbe?

Cadetto Entusiasta
12-12-2009, 15:06
Ho capito che per definire l'array dovrei fare


char vocali[5]={a,e,i,o,u};


però, dopo averlo definito, come faccio a metterlo in un for in modo tale che mi controlli le lettere?

cionci
12-12-2009, 16:09
Basta un if in cui controlli se tolower(carattere letto) è fra a, e, i, o, u.

Cadetto Entusiasta
12-12-2009, 16:34
E infatti, rovistando in tutto il materiale che ho a disposizione, l'esercizio in cui non mi doveva dare in output l'ho fatto così


#include <stdio.h>

int main()
{
int xc;
int n;

n = 0;
while ((xc = getchar()) != EOF)
{
n++;

if ((tolower(xc) == 'b') || (tolower(xc) == 'c') || (tolower(xc) == 'd') || (tolower(xc) == 'f') || (tolower(xc) == 'g') ||
(tolower(xc) == 'h') || (tolower(xc) == 'l') || (tolower(xc) == 'm') || (tolower(xc) == 'n') || (tolower(xc) == 'p') ||
(tolower(xc) == 'q') || (tolower(xc) == 'r') || (tolower(xc) == 's') || (tolower(xc) == 't') || (tolower(xc) == 'v') ||
(tolower(xc) == 'z') || (tolower(xc) == 'w') || (tolower(xc) == 'y') || (tolower(xc) == 'j') || (tolower(xc) == 'k') ||
(tolower(xc) == 'x'))
putchar(xc);
}

return 0;
}



e l'altro che mi deve far solo vedere le vocali così



#include <stdio.h>

int main()
{
int xc;
int n;

n = 0;
while ((xc = getchar()) != EOF)
{
n++;

if ((xc == 'a') || (xc == 'e') || (xc == 'i') || (xc == 'o') || (xc == 'u'))
putchar(xc);
}

return 0;
}



e così dovrebbero essere giusti. Mi chiedevo solo se c'era un'altra maniera per fare il secondo esercizio, limitando un pò le operazioni che il programma doveva eseguire, al posto degli ||..

cionci
12-12-2009, 16:51
E' il primo che è errato ;) Anzi, più che errato troppo prolisso.

Ti dico solo che il primo lo puoi fare con la stessa condizione del secondo leggermente modificata.

Cadetto Entusiasta
12-12-2009, 17:01
Si infatti, mi sono sbagliato, volevo intendere il primo esercizio.
In che senso sarebbe errato? Il secondo praticamente è uguale al primo, però non c'è il controllo sulle maiuscole delle vocali...

cionci
12-12-2009, 17:05
Te l'ho detto, non è proprio errato, è prolisso.
Puoi utilizzare la stessa condizione (inserendo anche il tolower magari) leggermente modificata anche nel primo.

Cadetto Entusiasta
12-12-2009, 17:12
Nel secondo posso inserire il tolower alle vocali. Lo so che è abbastanza lungo, ma non saprei un'altra maniera per accorciarlo..

cionci
12-12-2009, 17:24
Nel secondo posso inserire il tolower alle vocali. Lo so che è abbastanza lungo, ma non saprei un'altra maniera per accorciarlo..
Prendi la stessa identica condizione del secondo sulle vocali ed utilizzala nel primo al posto di quella sulle consonanti. Ovviamente serve una leggera modifica.

Cadetto Entusiasta
12-12-2009, 17:39
Però facendo così si prende il controllo sulle lettere maiuscole, vero? e nn è che si accorcia tanto...

Comunque dovrebbe essere così


#include <stdio.h>

int main()
{
int xc;
int n;

n = 0;
while ((xc = getchar()) != EOF)
{
n++;

if ((tolower(xc) == 'a') || (tolower(xc) == 'e') || (tolower(xc) == 'i') || (tolower(xc) == 'o') || (tolower(xc) == 'u'))
putchar(xc);
}

return 0;
}


premetto che non l'ho provato; se ho capito bene, è così che intendi?

cionci
12-12-2009, 17:43
Quasi, così è identico al secondo. A me sembra molto più corta la condizione nell'if.

Cadetto Entusiasta
12-12-2009, 17:44
Si, praticamente si, ho solo aggiunto il controllo dei tolower; altro non saprei fare in più

cionci
12-12-2009, 17:49
Si, praticamente si, ho solo aggiunto il controllo dei tolower; altro non saprei fare in più
Così però non stampa tutte le consonanti.

Se io scrivo:

if(condizione)
{
//stampo le vocali
}
else
{
//stampo le consonanti
}
Che operazione devo fare su "condizione" per fare in modo di poter scrivere:
if(nuova condizione)
{
//stampo le consonanti
}
else
{
//stampo le vocali
}

Mantenendo la stessa identica funzionalità del codice ?

Cadetto Entusiasta
12-12-2009, 18:04
In che senso non stampa tutte le consonanti? L'ho provato e in output mi da tutto..

Non ho capito cosa mi vuoi dire..

cionci
12-12-2009, 18:20
In che senso non stampa tutte le consonanti? L'ho provato e in output mi da tutto..
Volevo dire che in quel modo stampa tutte le consonanti, ma non le vocali.

Ti faccio un esempio più concreto:

if(a == b && c != d)
{
faccioQualcosa();
}
else
{
faccioQualcosaltro();
}

Scrivimi la condizione per cui il codice sotto sia equivalente a quello sopra:

if(.....)
{
faccioQualcosaltro();
}
else
{
faccioQualcosa();
}

blackgin
12-12-2009, 20:04
Volevo dire che in quel modo stampa tutte le consonanti, ma non le vocali.

Ti faccio un esempio più concreto:

if(a == b && c != d)
{
faccioQualcosa();
}
else
{
faccioQualcosaltro();
}

Scrivimi la condizione per cui il codice sotto sia equivalente a quello sopra:

if(.....)
{
faccioQualcosaltro();
}
else
{
faccioQualcosa();
}


il grande not ! =)

Cadetto Entusiasta
13-12-2009, 10:27
Volevo dire che in quel modo stampa tutte le consonanti, ma non le vocali.

Ti faccio un esempio più concreto:

if(a == b && c != d)
{
faccioQualcosa();
}
else
{
faccioQualcosaltro();
}

Scrivimi la condizione per cui il codice sotto sia equivalente a quello sopra:

if(.....)
{
faccioQualcosaltro();
}
else
{
faccioQualcosa();
}


Ma infatti per quel tipo di esercizio, mi veniva richiesto che dato un testo inserito dall'utente da tastiera, il programma in output doveva restituirlo senza vocali..


Per la cosa che mi vuoi far fare, penso che si dovrebbe far così


if(a!=b && c==d)
{
faccioQualcosaltro();
}
else
{
faccioQualcosa();
}

M4rk191
13-12-2009, 10:46
Invece di elencare tutte quelle condizioni utilizza uno switch. Le variabili char sono interi, puoi utilizzare i numeri decimali della codifica ASCII per riferirti alle lettere, inoltre la differenza tra le maiuscole e le minuscole è una costante, quindi potresti anche evitare l'utilizzo di tolower (che è appunto implementata sfruttando questa caratteristica del codifica).

cionci
13-12-2009, 10:51
No è errato ;)
Non so che scuola tu faccia. Hai mai sentito parlare delle leggi di De Morgan ?

M4rk191: che motivo avrebbe di rendere tutto più complicato ? Inoltre non importa utilizzare i numeri della codifica ASCII. Nei vari case si possono mettere anche i caratteri fra apici.

cionci
13-12-2009, 10:55
Ma infatti per quel tipo di esercizio, mi veniva richiesto che dato un testo inserito dall'utente da tastiera, il programma in output doveva restituirlo senza vocali..
Azz, ho riscritto male. Nel modo in cui l'avevi messe te qui (http://www.hwupgrade.it/forum/showpost.php?p=30050988&postcount=15) non fa quello che chiede l'esercizio, cioè stampa solo le vocali.

M4rk191
13-12-2009, 10:57
M4rk191: che motivo avrebbe di rendere tutto più complicato ? Inoltre non importa utilizzare i numeri della codifica ASCII. Nei vari case si possono mettere anche le i caratteri fra apici.
non mi sembra più complicato, con le condizioni nello if, ci sono vari operatori logici che con lo switch si eviterebbero, inoltre mi sembra più comodo scrivere i numeri che le lettere tra apici singoli. Comunque sia, ognuno ha il proprio modo di vedere le cose, era solo un consiglio :boh:

cionci
13-12-2009, 11:02
non mi sembra più complicato, con le condizioni nello if, ci sono vari operatori logici che con lo switch si eviterebbero,
Con 5 condizioni nell'if è troppo complicato ?
inoltre mi sembra più comodo scrivere i numeri che le lettere tra apici singoli.
Anche più leggibile ? Secondo me è anche meno comodo, visto che bisogna andarsi a vedere i valori delle lettere.

Cadetto Entusiasta
13-12-2009, 13:58
No, le leggi di De Morgan non le ho ancora sentite..è un male?

Ricapitolando, il un esercizio mi chiedeva "Fare un programma (chiamato novoc) che copi tutto l'input sull'output, tranne le vocali" e io l'ho fatto così


#include <stdio.h>

int main()
{
int xc;
int n;

n = 0;
while ((xc = getchar()) != EOF)
{
n++;

if ((tolower(xc) == 'b') || (tolower(xc) == 'c') || (tolower(xc) == 'd') || (tolower(xc) == 'f') || (tolower(xc) == 'g') ||
(tolower(xc) == 'h') || (tolower(xc) == 'l') || (tolower(xc) == 'm') || (tolower(xc) == 'n') || (tolower(xc) == 'p') ||
(tolower(xc) == 'q') || (tolower(xc) == 'r') || (tolower(xc) == 's') || (tolower(xc) == 't') || (tolower(xc) == 'v') ||
(tolower(xc) == 'z') || (tolower(xc) == 'w') || (tolower(xc) == 'y') || (tolower(xc) == 'j') || (tolower(xc) == 'k') ||
(tolower(xc) == 'x'))
putchar(xc);
}

return 0;
}



e l'ho appena provato e va bene.


Il secondo, mi chiede "Fare un programma (chiamato nocon) che copi tutto l'input sull'output, tranne le consonanti" e l'ho fatto così

#include <stdio.h>

int main()
{
int xc;
int n;

n = 0;
while ((xc = getchar()) != EOF)
{
n++;

if ((tolower(xc) == 'a') || (tolower(xc) == 'e') || (tolower(xc) == 'i') || (tolower(xc) == 'o') || (tolower(xc) == 'u'))
putchar(xc);
}

return 0;
}



e anche questo va bene.

Cosa mi volete suggerire/spiegare di fare?

cionci
13-12-2009, 15:08
Di usare la seconda condizione nel primo.
http://it.wikipedia.org/wiki/Teoremi_di_De_Morgan
La condizione diventerebbe così:

if(a != b || c == d)
{
faccioQualcosaltro();
}
else
{
faccioQualcosa();
}
Il tuo primo esercizio è esattamente il complementare del secondo.
In pratica posso riscrivere il primo in questo modo:

#include <stdio.h>

int main()
{
int xc;
int n;

n = 0;
while ((xc = getchar()) != EOF)
{
n++;

if (tolower(xc) == 'a' || tolower(xc) == 'e' || tolower(xc) == 'i' || tolower(xc) == 'o' || tolower(xc) == 'u')
{
}
else
{
putchar(xc);
}

}

return 0;
}

Poi puoi modificare così:
if (!(tolower(xc) == 'a' || tolower(xc) == 'e' || tolower(xc) == 'i' || tolower(xc) == 'o' || tolower(xc) == 'u'))
{
putchar(xc);
}
else
{

}

Ho semplicemente negato a tutta la condizione (ho raggruppato fra tonde e messo un ! davanti) ed invertito i rami dell'if.
Ora potrebbe già andare bene, ma applicando De Morgan:
if (tolower(xc) != 'a' && tolower(xc) != 'e' && tolower(xc) != 'i' && tolower(xc) != 'o' && tolower(xc) != 'u')
{
putchar(xc);
}

Cadetto Entusiasta
13-12-2009, 16:34
Ma in realtà, forse su DeMorgan ho visto qualcosa, infatti per fare questo


if(a == b && c != d)
{
faccioQualcosa();
}
else
{
faccioQualcosaltro();
}


mi sembrava che si dovesse "ribaltare"/negare tutto. Ma ne terrò conto in futuro e vedrò di saperne di più.

Dovrei aver capito, praticamente come lo facevo io non era giustissimo, anche se in realtà il testo non esplicava bene come doveva essere il testo in output, cioè se dovevano essere tutte attaccate o meno; con DeMorgan il testo tiene la formattazione che ha in input, con gli spazi tra le parole ma senza le vocali. E questo tutto grazie a DeMorgan, mmmh, è proprio da tener presente.

Ma quindi la stessa cosa la posso fare con il programma con output senza le consonanti? E' giusto così?


#include <stdio.h>

int main()

{
int xc;
int n;

n = 0;
while ((xc = getchar()) != EOF)
{
n++;

if (tolower(xc) != 'b' && tolower(xc) != 'c' && tolower(xc) != 'd' && tolower(xc) != 'f' && tolower(xc) != 'g' &&
tolower(xc) != 'h' && tolower(xc) != 'l' && tolower(xc) != 'm' && tolower(xc) != 'n' && tolower(xc) != 'p' &&
tolower(xc) != 'q' && tolower(xc) != 'r' && tolower(xc) != 's' && tolower(xc) != 't' && tolower(xc) != 'v' &&
tolower(xc) != 'z' && tolower(xc) != 'w' && tolower(xc) != 'y' && tolower(xc) != 'j' && tolower(xc) != 'k' &&
tolower(xc) != 'x')
{
putchar(xc);
}
}

return 0;
}

cionci
13-12-2009, 16:42
Negare tutto, poi negare i membri e trasformare gli and in or e viceversa.

Vedi non avevo pensato agli spazi. In effetti cambiando la condizione sul secondo anche il secondo funziona allo stesso modo del primo.
Sì lo puoi fare anche con il secondo.

Cadetto Entusiasta
14-12-2009, 07:47
Bene...buono...sinceramente ho tribulato a capire le cose, ma almeno adesso le ho capite.
I miei più sentiti ringraziamenti. Alla prossima.
FB