Newsgroup: it.comp.lang.c
Titolo: Vocali e consonanti

Mi sapreste dire perche con le consonanti funziona mentre per le vocali no?
#include <stdio.h>
#define MAXCOL 5
#define MAXRIG 4
int leggi(void);
int vocali(int);
int consonanti(int);
main()
{
  int  i,k;
  char codificato[MAXRIG][MAXCOL];
  char originale[MAXRIG][MAXCOL];
  char car;
  i=0;
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
         originale[i][k]=leggi();
  originale[i-1][k-1]='\0';
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
      {
       codificato[i][k]=originale[i][k];
       car=originale[i][k];
       codificato[i][k]=vocali(car);
      }
   for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
      {
       codificato[i][k]=originale[i][k];
       car=originale[i][k];
       codificato[i][k]=consonanti(car);
       }
  printf("%s \n",originale,"\n");
  system("PAUSE");
  printf("%s \n",codificato,"\n");
  system("PAUSE");
  return 0;
}
int leggi(void)
{
  int i,c;
  c=getchar();
  return c;
}
int vocali(int c)
 {
  char vocali[]={'a','e','i','o','u'};
  int i,k;
  k=10;
  for(i=0;i<5;i++)
   {
     if(c==vocali[i])
        if(i==0)
           k=4;
        else
          k=i+1;
    }
    if (k!=10)
       c=vocali[k];
    return c;
 }
 int consonanti(int c)
 {
  char 
consonanti[]={'b','c','d','f','g','h','l','m','n','p','q','r','s','t','v','z'};
  int i,k;
  k=18;
  for(i=0;i<15;i++)
   {
     if(c==consonanti[i])
        if(i==0)
           k=15;
        else
          k=i+1;
    }
    if (k!=18)
       c=consonanti[k];
    return c;
 }

a me non va' proprio sto programma...
spiega la traccia del problema, che vediamo di aiutarti, magari rifacendolo 
da 0... 

Cosa non ci vedi chiaro?
Comunque la traccia è questa
  1.. algoritmo per crittografare e decrittografare un testo di 80x20 
caratteri. L'algoritmo deve usare il seguente semplice codice a 
sostituzione: ogni consonante dell'alfabeto è sostituita dalla consonante 
precedente nell'ordine alfabetico, per es. b diventa z, p diventa n, c 
diventa b,..., v diventa t, z diventa v; ogni vocale è sostituita dalla 
vocale precedente; numeri e simboli di interpunzione rimangono inalterati.

ora e' + chiaro...
domani ti rispondo che stasera ho sonno...
hai letto il mio thread sul programma autolavaggio ?
dacci un'occhiata !!! 

 
In ogni caso, lasciatelo dire: fai un sacco di cicli completamente
inutili...
-- 
Roberto -MadBob- Guido
mail bob4mail***@***
gmail.com
web 
http://madbob.homelinux.com
BrainTop Project maintainer - 
http://braintop.sf.net

Indipendentemente da tutto, comunque non fa controlli sulle vocali.
Non so spegarmelo, anche perkè per le consonanti funziona.
N.B.
programmo (parola grossa) da poco in c, sono aperto a qualsiasi tipo di 
suggerimento 

il testo lo vuoi prendere carattere per carattere oppure stringa intera ?
perche' se lo prendi lettera per lettera, puoi mettere tutto direttamente in 
una matrice di 80 x 20, piu' facile da controllare... 

Fabio io ti ringrazio della disponibilità ma a me piacerebbe sapere perchè 
così come l'ho strutturato io funziona per le consonanti ma non per le 
vocali
Io non me lo riesco a spiegare.


Secondo me non funziona neanche per le consonanti....
Intanto le consonanti sono 16 e non 15 (anche assumendo di dimenticarsi
di jkwxy).
Poi non puoi stampare originale e convertito con "%s": non sono stringhe.
(Il compilatore si lamenta, se setti l'opzione di compilazione a -Wall)
Poi un errore fondamentale (sia per le vocali sia per le consonanti...)
   for(i=0;i<5;i++)
    {
      if(c==vocali[i])
         if(i==0)
            k=4;
         else
           k=i+1;
     }
non si capisce se stai codificando o decodificando....
Per codificare devi prendere il carattere precedente,
quindi
if (i==0) k=4;
else k=i-1;
mentre tu scrivi k=i+1;
questo fa si che se per caso la vocale era 'u', tu poni k=4+1=5
e quindi "sfori" fuori dalle vocali.
La stessa cosa per le consonanti...
ciao,
g.

 printf("%s \n",codificato,"\n");
da matrici sono diventate stringhe, com'e' sta cosa ?
in teoria dovresti fare 2 cicli for per ogni stringa, cioe' 2 cicli per 
l'originale e 2 per la codificata... 

altra cosa:
le consonanti si spostano in avanti, ovvero se metto C mi da' D, S mi da' T, 
le vocali non cambiano nemmeno a pagarle, i segni rimangono (almeno quelli)
e' un bel po' da ricontrollare 

con il debug in un primo momento la parola "casa" codificata diventa dusu, 
poi si corregge in data...
mi sa che ci sono le funzioni vocali e consonanti proprio fuori, prima da' 
le vocali giuste (cioe' trasforma casa in dusu, il che e' giusto, pero' non 
tocca le consonanti), poi all'improvviso le vocali tornano uguali...
bah sto andando in pallone... 

Forse ti ho dato la versione sulla quale ho fatto diverse prove, questa è 
l'ultima:
#include <stdio.h>
#define MAXCOL 5
#define MAXRIG 4
int leggi(void);
int vocali(int );
int consonanti(int);
main()
{
  int  i,k;
  char codificato[MAXRIG][MAXCOL];
  char originale[MAXRIG][MAXCOL];
  char car;
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
         originale[i][k]=leggi();
  originale[i-1][k-1]='\0';
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
      {
       codificato[i][k]=originale[i][k];
       car=originale[i][k];
       codificato[i][k]=vocali(car);
      }
   for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
      {
       codificato[i][k]=originale[i][k];
       car=originale[i][k];
       codificato[i][k]=consonanti(car);
      }
  printf("\n originale \n");
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
         printf("%c" ,originale[i][k]);
  system("PAUSE");
   printf("\n codificato \n");
   for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
        printf("%c",codificato[i][k]);
    printf("\n");
    system("PAUSE");
  return 0;
}
int leggi(void)
{
  int i,c;
  c=getchar();
  return c;
}
int vocali(int c)
 {
  char vocali[]={'a','e','i','o','u'};
  int i,k;
  k=10;
  for(i=0;i<5;i++)
    {
     if(c==vocali[i])
       {
        if(i==0)
           k=4;
        else
          k=i+1;
        }
    }
    if (k!=10)
       c=vocali[k];
    return c;
 }
int consonanti(int c)
 {
  char 
consonanti[]={'b','c','d','f','g','h','l','m','n','p','q','r','s','t','v','z'};
  int i,k;
  k=18;
  for(i=0;i<16;i++)
   {
     if(c==consonanti[i])
        if(i==0)
           k=15;
        else
          k=i-1;


Vedi se ti piace cosě:
include <stdio.h>
#define MAXCOL 5
#define MAXRIG 4
int leggi(void);
int codifica(int );
/*int consonanti(int);*/
main()
{
  int  i,k;
  char codificato[MAXRIG][MAXCOL];
  char originale[MAXRIG][MAXCOL];
  char car;
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
         originale[i][k]=leggi();
  originale[i-1][k-1]='\0';
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
      {
       car=originale[i][k];
       codificato[i][k]=codifica(car);
      }
  printf("\n originale \n");
  for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
         printf("%c" ,originale[i][k]);
  system("PAUSE");
   printf("\n codificato \n");
   for(i=0;i<MAXRIG;i++)
     for(k=0;k<MAXCOL;k++)
        printf("%c",codificato[i][k]);
    printf("\n");
    system("PAUSE");
  return 0;
}
int leggi(void)
{
  int i,c;
  c=getchar();
  return c;
}
int codifica(int c)
 {
  char vocali[]={'a','e','i','o','u'};
  char 
consonanti[]={'b','c','d','f','g','h','l','m','n','p','q','r','s','t','v','z'};
  int i,k;
  k=10;
  for(i=0;i<5;i++)
    {
     if(c==vocali[i])
       {
        if(i==0)
           k=4;
        else
          k=i+1;
        }
    }
    if (k!=10)
       c=vocali[k];
    else
      {


         }
questo continua ad essere sbagliato....
g.

> system("PAUSE");
cos'e' sta cosa ? non esiste sul mio visual c ?
bah, comandi strani !!!

ora funziona
ho provato a inserire "casa" e mi da' "buru"
quindi funziona !!!
dov'e' il problema
p.s.: togli system("PAUSE"); che non ti serve a nulla !!! 

Sto usando dev c++ e se non inserisco system("PAUSE")
non mi blocca l'output 

cmq ora funziona ?
hai altri problemi da risolvere ? 

Per adesso ho finito, devo solo fare una relazione e spedire via e-mail al 
prof
Ti ringrazio
bibop 

 ha scritto nel messaggio 
news:d20oil$au6$1...@newsfeed.cineca.it...

Ciao Giovanni,
non ho ancora capito se nella codifica deve avanzare o retrocedere; se 
l'indice è 0, l'indice di codifica (k) lo muove in fondo come andasse 
indietro ma in caso contrario lo incrementa. Ti chiedo lumi.
Un saluto. 

 ha scritto nel messaggio 
news:RWT0e.10329$IN.2...@twister2.libero.it...



Ciao,
questo l'ho intuito, ma spiegami questo:
Hai un array di vocali:
{'a', 'e', 'i', 'o', 'u'}
   0   1    2   3   4
Ora fai la ricerca ed 'i' indicizza la vocale che hai trovato.
A qusto punto inizializzi l'indice di codifica e dici:
if(i == 0) /* i sta puntando ad 'a' */
    k = 4;   /* k punterà a 'u' */
else
    k = i + 1;    /* Cioè se, per esempio, 'i' vale 1 e cioè indicizza 'e', 
mi aspetto che, per coerenza con quanto scritto sopra, tu con 'k' venga 
indietro di 1 e vada ad indicizzare 'a' fosse anche solo per il fatto che 
così come stai facendo la vocale 'a' non la userai mai! */
Quindi mi aspetterei:
se stai andando indietro
if(i == 0)
    k = 4;
else
    k = i - 1;
se stai andando avanti
k = (i + 1) % 5;
Spero di esser stato più chiaro nell'esporti i miei dubbi.
 

Hai ragione c'eara un piccolo errore di copia incolla
for(i=0;i<5;i++)
    {
     if(c==vocali[i])
       {
        if(i==0)
           k=4;
        else
          k=i-1;
        }
    }
Questo č il nuovo ciclo.
N.B
Mi sai spiegare quest'istruzione?
che significa il  %4?


 wrote

Lasciando stare la perdita di tempo degli 80x20 caratteri, ecco un modo 
snello ma piu' che altro leggibile per far quello che vuoi:
char Funzione(char c)
{
    /* array di conversione */
    static char alfabeto[] = {
        'U', 'Z', 'B', 'C', 'A', 'D', 'F', 'G', 'E', 'H', 'J', 'K', 'L',
        'M', 'I', 'N', 'P', 'Q', 'R', 'S', 'O', 'T', 'V', 'W', 'X', 'Y'
    };
    /* se non e' una lettera lasciamo c invariato */
    if(!isalpha(c))
         return c;
    /* conversione */
    return (alfabeto[toupper(c)-'A'] + (c-toupper(c)));
}
funziona sia per le lettere maiuscole che minuscole, ad esempio:
"caSA 123 ;; abc XYZ", diventa:
"buRU 123 ;; uzb WXY"
se hai paura che cancellando per sbaglio una delle lettere dall'array tu 
possa scrivere oltre l'array allora puoi piazzare un bel:
"assert( sizeof(alfabeto)==(('Z'-'A')+1) );" che, in versioni di debug, si 
prende la briga di controllare questa cosa ed in versioni release invece no.
Magari credi che questo algoritmo "bari", ma la verita' e' che anche nel tuo 
usi due array per un numero totale di ('Z'-'A')+1 elementi. Quindi il tuo 
algoritmo ed il mio entrambi allocano lo stesso numero di elementi (questo 
se non ti fossi dimenticato alcune consonanti!). Visto che usi array, tanto 
vale che essi siano gia' di conversione e non di lettere in ordine 
normale... Volendo (piu' che altro se il problema richiedesse un array di 
conversione molto piu' grande) potresi creare l'array di conversione 
dinamicamente at-run-time all'inizio dell'applicazione.
Ad ogni modo, tornando al codice, ora, invece di avere di avere due funzioni 
da chiamare, consonanti() e vocali() e chiamarle entrambe su ogni lettera 
del testo (chami anche consonanti() per le vocali e vocali() per le 
consonanti), ora hai una sola chiamata da fare.
Per finire eri pieno di cicli inutili:
int consonanti(int c)
{
    char consonanti[]={
        'b','c','d','f','g','h','l','m',
        'n','p','q','r','s','t','v','z'
    };
    int i,k;
    k=18;
    for(i=0;i<15;i++)
    {
        if(c==consonanti[i])
            if(i==0)
                k=15;
            else
                k=i+1;
    }
    if (k!=18)
        c=consonanti[k];
    return c;
}
in pratica per ogni lettera, allocavi un array di consonanti (visto che non 
e' statico, ok, non e' grande), poi iteravi 15 volte per scorrere l'array, 
poi invocavi vocale, alllocavi un piccolo array di vocali e poi iteravi 5 
volte per scorrere il nuovo array.
Come vedi nel mio codice uso un array statico cosi' che venga allocato una 
sola volta e poi non ci sono cicli.
Immagino che le "prestazioni" non siano un problema in questo caso, ad ogni 
modo c'e' da porsi la domanda: "quanto del codice che hai scritto e' 
inutile?", probabilmente intorno al 90%. Piu' codice inutile ci metti, piu' 
possibilita' hai di avere bugs, piu' tempo ci metti a programmarlo ed infine 
ci metti pure di piu' a testarlo e se c'e' un bug a trovare il bug; tanto 
vale che hai chiesto aiuto al NG perche' non sei riuscito a trovarlo.
Il mio consiglio e' quello di non essere una code-monkey e mettersi a 
programmare subito sperando di risolvere il problema, ma di soffermarsi 
prima a pensare quale sia la soluzione migliore. Io ho scelto la mia, non 
pretendo che ti piaccia, e' questione di gusti e di compromessi, il punto e' 
che mi sono fermato a riflettere ed ho scritto un codice breve, che usa 
funzioni standard (quindi testate), che non abbia cicli ed altre cose 
inutili in questo caso e che (incrociando le dita) non contenga bugs.
Spero questo ti possa aiutare.
Tommaso


Beh, '%' è, in C, l'operatore matematico modulo che corrisponde al mod del 
vb (calcola il resto di una divisione senza decimali). Quindi per "(i + 1) % 
4" se i vale:
0 -> 1
1 -> 2
2 -> 3
3 -> 0
4 -> 1
5 -> 2
6 -> 3
7 -> 0
.
.
.
Comunque ricorda che le vocali sono 5.
Spero di essere stato utile.
Un saluto.