Oppure

Loading
02/02/14 16:13
perillitommaso
Ciao a tutti, ho un "piccolo" problemino nel creare un programma che, letta una stringa di caratteri, trasformi le vocali minuscole in maiuscolo, e le consonanti maiuscole in minuscolo ... ho cercato un po' su internet ma non ho trovato un gran che, vi lascio il codice sorgente, ci sto lavorando..
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // libreria della stringa 

#define MAX 30 // stabiliamo la lunghezza massima della stringa, quindi 29 caratteri
/*
Aquisito una stringa, calcolarne la lunghezza attuale, trasformare in maiuscolo le vocali e 
in minuscolo le consonanti, lasciando in pace i caratteri speciali e le cifre numeriche
*/

int main()
{
    //dichiariamo le variabili di tipo char e int
    char stringa[MAX];
    int lung, i;
    
    printf("Inserisci una frase: ");
    fgets (stringa, MAX, stdin); // leggiamo la variabile stringa inserita da tastiera
    lung = strlen(stringa); //contiamo i caratteri della stringa con la funzione "strlen"
    printf("\nLa stringa e' composta da: %d caratteri", lung); //stampiamo i caratteri della stringa 
    i=0; // inizializziamo il contatore dei caratteri a 0
    while (i<lung){ // entriamo nel ciclo fin quando i diventa uguale alla lunghezza della stringa
      //selezione delle vocali minuscole
      if((stringa[i]=='a')||(stringa[i]=='e')||(stringa[i]=='i')||(stringa[i]=='o')||(stringa[i]=='u'))
      {
        stringa[i] = toupper(stringa[i]); //funzione "toupper" che trasforma il carattere in maiuscolo
      }
        i=i+1; //incrementiamo il contatore dei caratteri
    }
    

    return 0;
}

il codice non è finito.. se ho codificato per bene mi mancano le consonanti, grazie a tutti :)
aaa
02/02/14 17:34
Poggi Marco
Ciao!

Per utilizzare la funzione toupper( ) , è necessario includere l' header ctype.h.
( cplusplus.com/reference/cctype/ )

Per le consonanti aggiungi else all' if e usa il metodo tolower( ) .
aaa
02/02/14 17:48
perillitommaso
Grazie molte per la risposta, ho modificato il mio sorgente ma ho un dubbio, quando vado ad aggiungere l'else all'if, il programma poi mi considera tutti gli altri casi come per esempio le vocali in maiuscolo oppure i numeri o i caratteri speciali, mi sbaglio oppure no?
aaa
02/02/14 18:08
Poggi Marco
E' esattamente come dici. In questi casi, è più utile usare lo switch.
Per i caratteri simbolici, numerici o lettere accentate, i metodi toupper( ) e tolower( ) non efettuano cambiamenti.
aaa
03/02/14 15:31
perillitommaso
Grazie mille Marco ^^ il programma funziona perfettamente, posto il codice sorgente in modo che tutti possano vederlo se ne hanno bisogno
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // libreria della stringa 
#include <ctype.h> // libreria per utilizzare le funzioni " toupper" e "tolower"

#define MAX 30 // stabiliamo la lunghezza massima della stringa, quindi 29 caratteri
/*
Aquisito una stringa, calcolarne la lunghezza attuale, trasformare in maiuscolo le vocali e 
in minuscolo le consonanti, lasciando in pace i caratteri speciali e le cifre numeriche
*/

int main()
{
    //dichiariamo le variabili di tipo char e int
    char stringa[MAX];
    int lung, i;
    
    printf("Inserisci una frase: ");
    fgets (stringa, MAX, stdin); // leggiamo la variabile stringa inserita da tastiera
    lung = strlen(stringa); //contiamo i caratteri della stringa con la funzione "strlen"
    lung = lung-1;//togliamo 1 perchè la funzione "strlen" conta anche il carattere "a capo"
    printf("\nLa stringa e' composta da: %d caratteri\n", lung); //stampiamo i caratteri della stringa 
    i=0; // inizializziamo il contatore dei caratteri a 0
    while (i<lung){ // entriamo nel ciclo fin quando i diventa uguale alla lunghezza della stringa
      //selezione delle vocali minuscole
      if((stringa[i]=='a')||(stringa[i]=='e')||(stringa[i]=='i')||(stringa[i]=='o')||(stringa[i]=='u'))
      {
        stringa[i] = toupper(stringa[i]); //funzione "toupper" che trasforma il carattere in maiuscolo
      }
      else
      {
           switch(stringa[i]) //selezione multipla delle consonati maiuscole
           {
             case 'B': stringa[i] = tolower(stringa[i]);//funzione "tolower" che strasforma il carattere in minuscolo
             case 'C': stringa[i] = tolower(stringa[i]);
             case 'D': stringa[i] = tolower(stringa[i]);
             case 'F': stringa[i] = tolower(stringa[i]);
             case 'G': stringa[i] = tolower(stringa[i]);
             case 'H': stringa[i] = tolower(stringa[i]);
             case 'L': stringa[i] = tolower(stringa[i]);
             case 'M': stringa[i] = tolower(stringa[i]);
             case 'N': stringa[i] = tolower(stringa[i]);
             case 'P': stringa[i] = tolower(stringa[i]);
             case 'Q': stringa[i] = tolower(stringa[i]);
             case 'R': stringa[i] = tolower(stringa[i]);
             case 'S': stringa[i] = tolower(stringa[i]);
             case 'T': stringa[i] = tolower(stringa[i]);
             case 'V': stringa[i] = tolower(stringa[i]);
             case 'Z': stringa[i] = tolower(stringa[i]);
             break;
           }
      } 
      
        i=i+1; //incrementiamo il contatore dei caratteri
    }
    printf("\n Stringa trasformata:\n %s\n\n",stringa); //visualizzazione della stringa strasformata

    system("PAUSE");
}
aaa
04/02/14 13:44
Qwertj
Un tantino ridondante!
E non funzionerebbe in caso di vocali già maiuscole o consonanti già minuscole.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
 
#define MAX 30
/*
Aquisito una stringa, calcolarne la lunghezza attuale, trasformare in maiuscolo le vocali e
in minuscolo le consonanti, lasciando in pace i caratteri speciali e le cifre numeriche
*/
 
int main()
{
    char stringa[MAX];
    int lung;
   
    printf("Inserisci una frase: ");
    fgets (stringa, MAX, stdin); 
    lung = strlen(stringa); 
    lung = lung-1;
    printf("\nLa stringa e' composta da: %d caratteri\n", lung); 

    for(int i = 0; i < lung; ++i) //il for è fatto per questo!!
    {
        //mettiamo tutto minuscolo
        stringa[i] = tolower(stringa[i]);
        //se è una vocale
        if(stringa[i] == 'a' || stringa[i] == 'e' || stringa[i] == 'i' || stringa[i] == 'o' || stringa[i]=='u')
        {
            stringa[i] = toupper(stringa[i]);
        } //altrimenti è una consonante, ma è già stata trasformata in minuscolo all'inizio del ciclo
    }
    
    printf("\n Stringa trasformata:\n %s\n\n", stringa);
 
    system("PAUSE");
}

Basta che metti minuscolo ogni carattere, e se è una vocale (ti conviene così e non il contrario perchè le vocali sono solo 5...) lo metti maiuscolo. Così hai la garanzia di lavorare solo con caratteri minuscoli nella condizione.

Quel while(i < lung) non si può vedere: esistono i cicli for per un motivo, una cosa del genere è illeggibile (devi andare a cercarti in tutto il corpo del while l'incremento di i per capirci qualcosa)
Tra l'altro i contatori è buona norma dichiararli nell'istruzione di inizializzazione per far si che non abbiano scope al di fuori del for: questo garantische che (a) non si lavori con contatori non azzerati per sbaglio, (b) sia facilmente individuabile un loro uso scorretto all'esterno del ciclo e (c) lavori sempre con gli stessi contatori (nessuno ti impedirebbe di dichiare di nuovo i successivamente nel programma) senza riempire il programma di dichiarazioni fantastiose (tipo int i, j, k, n, m, a, b, c, c1, c2 (visto, sigh) :pat: )
In generale, meno scope riesci a dare a una variabile, meglio è (per questo globale = evil solitamente)

Nello switch, se non metti il break dopo le etichette case, l'esecuzione non salta ed esegue anche tutte le etichette seguenti: se nel tuo programma qualcuno avesse inserito una 'B', il carattere sarebbe stato passato a tolower() ben 14 volte!
Per proseguire sulla tua falsa riga, sarebbe stato
switch(stringa[i]) {
    //l'istruzione "case x:" dice al programma: inizia a eseguire lo switch da qua
    //con break invece lo fai uscire dallo switch
    //tutto quello che incontra tra il case corrispondente e il primo "break" dopo,
    //viene eseguito, anche se fa parte di altri case!
    case 'B':
    case 'C':
    case 'D':
    case 'F':
    case 'G':
    case 'H':
    case 'L':
    case 'M':
    case 'N':
    case 'P': 
    case 'Q':
    case 'R':
    case 'S':
    case 'T':
    case 'V':
    case 'Z':
         stringa[i] = tolower(stringa[i]);
    break; //superfluo, visto che è in fondo, ma metterlo non fa male (se dovessi aggiungere delle etichette dopo?)
}

In ogni caso, analizzando la condizione dell'if, capiamo che è inutile perdere del tempo su questo switch:
if(stringa[j] == 'a' || stringa[j] == 'e' || stringa[j] == 'i' || stringa[j] == 'o' || stringa[j] == 'u') {
    //1
} else {
    //2
}

Il blocco di codice 1 verrà eseguito solo se stringa[j] è una vocale, di conseguenza, il blocco 2 verrà eseguito solo se stringa[j] non è una vocale: per definizione quindi, il blocco 2 sarà eseguito quando stringa[j] è una consonante. Quindi controllare che sia una consonante è superfluo.
Potrebbe essere un carattere non alafabetico: in questo caso però nè toupper() nè tolower() lo modificheranno, quindi eseguirlo o meno non cambierà l'output del programma.

:yup:
Ultima modifica effettuata da Qwertj 04/02/14 13:46
aaa