[C] Array di caratteri

di il
38 risposte

[C] Array di caratteri

Salve a tutti,

Sono nuovo e mi sono appena presentato nell'apposito topic.

Sto affrontando lo studio dell'esame di Elementi di Informatica da 6 CFU.
Ho seguito questo corso anni fa con un professore che faceva usare il C.
Purtroppo non sono riuscito a dare questo esame con lui e, nel frattempo, il nuovo professore ha cominciato a tenere un corso in C/C++ (insomma ha "mantenuto la retrocompatibilità" coi vecchi alunni).

Nell'ultimo esame che, purtroppo, non sono riuscito a passare, vi era una traccia basata tutta sugli array di caratteri.
Io ero abituato a trattare con le stringhe e ad utilizzare funzioni come la getchar () ma, a quanto pare, non essendo in programma non ne era consentito l'utilizzo; inoltre la traccia chiedeva espressamente l'inizializzazione di un array di caratteri e non di una stringa.

Ad ogni modo, mi sono documentato in questi giorni e sono riuscito a scrivere questo pezzo di codice che compila e funziona. Tuttavia ho sentito la necessità di chiedere a qualcuno più esperto di me se il programma in questione sia "formalmente" corretto.

Questa è la traccia, io ho completato per adesso solo alcuni punti



E questo è il mio codice

#include <stdio.h>
#define MAX_C 20

char V [MAX_C];

void gestioneSequenza (void);
int immissione (void);
void stampaElemento (int, int);
void stampa (int);
void stampaInversa (int);

int main () {
  gestioneSequenza();
}

void gestioneSequenza () {
  int n;
  int scelta = -1;
  int pos;

  while (scelta != 0) {

    printf ("\n***** MENU' *****");
    printf ("\n1. Immissione caratteri e stampa rovescia\n");
    printf ("\n2. Stampa array di caratteri\n");
    printf ("\n3. Stampa elemento\n");
    printf ("\n0. Fine\n");
    printf ("***** FINE MENU' *****\n");

    printf ("\nScegli un'opzione dal menu': ");
    scanf ("%d", &scelta);

  switch (scelta) {
    case 1: n=immissione();
    stampaInversa(n);
    break;
    case 2: stampa(n);
    break;
    case 3: printf ("\nInserisci posizione da stampare: ");
    scanf ("%d", &pos);
    stampaElemento (n, pos);
    break;
  }
  }
}

int immissione () {
  
  int n;
  int i;
  char invio;

  printf ("\nQuanti caratteri desideri inserire? ");
  scanf ("%d", &n);
  
  for (i=0;i<n;i++) {
    printf ("\nInserisci %d° carattere: ", i+1);
    scanf ("%c", &invio);
    scanf ("%c", &V[i]);
  }

  return n;
}

void stampa (int n) {
int i;
 for (i=0; i<n; i++) {
   printf ("\nIl %d° carattere e': %c\n", i+1, V[i]);
 }
 }

void stampaElemento (int n, int pos) {

int i;

 for (i=0;i<n;i++) {
   if(pos==i) {
     printf ("\nLa posizione %d e' occupata dall' elemento %c\n", pos, V[i]);
   }
   }
}

void stampaInversa (int n) {
int i;
 for (i=n-1; i>=0; i--) {
   printf ("\nIl %d° carattere e': %c\n", i+1, V[i]);
 }
 }
Grazie a chiunque mi dia una mano.

38 Risposte

  • Re: [C] Array di caratteri

    La funzione stampaElemento è profondamente sbagliata!
    1) usa SEMPRE nomi descrittivi per le variabili, lunghi!
    2) bisogna sempre controllare la validità del input, in questo caso quantomeno "pos"
    3) non occorre fare un ciclo: hai un vettore e l'indice dell'elemento che cerchi!
    4) quando fai un ciclo che cerca un singolo elemento, dopo averlo trovato è opportuno terminare forzatamente il ciclo (break).
    5) l'indentazione delle {} è scorretta
    6) usa gli spazi! Dopo i segni di punteggiatura aiutano la leggibilità.
    7) quando dichiari le funzioni metti i nomi dei parametri, non limitarti al loro tipo.
    N
  • Re: [C] Array di caratteri

    Ti ringrazio per la risposta, sono proprio negato con questo esame.

    Apporterò le modifiche necessarie
  • Re: [C] Array di caratteri

    Ecco qui il codice modificato
    
    #include <stdio.h>
    #define MAX_C 20		// Il masssimo numero di caratteri modificabile in base alle esigenze.
    
     char V[MAX_C];
    
    void gestioneSequenza (void);	// Gestisce il menu' e la scelta dell'utente.
    int immissione (void);		// Riempie il vettore con i caratteri.
    void stampaElemento (int numeroElementi, int posizione);	/*Stampa l'elemento alla posizione j-esima selezionata dall'utente. */
    void stampa (int numeroElementi);	//Stampa il vettore.
    void stampaInversa (int numeroElementi);	//Stampa il vettore in maniera inversa.
    
    int 
    main () 
    {
      
     
    gestioneSequenza ();	//Il main richiama semplicemente la funzione gestioneSequenza.
    } 
     
    void 
    
    
    gestioneSequenza () 
    {
      
     
    int numeroElementi;
      
     
    int scelta = -1;
      
     
    int posizione;
      
     
     
    while (scelta != 0)
        
        {
          
     
     
    printf ("\n***** MENU' *****");
          
     
    printf ("\n1. Immissione caratteri e stampa rovescia\n");
          
     
    printf ("\n2. Stampa array di caratteri\n");
          
     
    printf ("\n3. Stampa elemento\n");
          
     
    printf ("\n0. Fine\n");
          
     
    printf ("***** FINE MENU' *****\n");
          
     
     
    printf ("\nScegli un'opzione dal menu': ");
          
     
    scanf ("%d", &scelta);
          
     
     
    switch (scelta)
    	
    	{
    	
     
    case 1:
    	  
    numeroElementi = immissione ();	//Il numero di elementi viene reso noto a tutte le funzioni.
    	  stampaInversa (numeroElementi);
    	  
     
    break;
    	
     
    case 2:
    	  
    stampa (numeroElementi);
    	  
     
    break;
    	
     
    case 3:
    	  
    printf ("\nInserisci posizione da stampare: ");
    	  
     
    scanf ("%d", &posizione);
    	  
     
    stampaElemento (posizione, numeroElementi);
    	  
     
    break;
    	
     
    }
        
     
    }
    
     
    }
    
    
     
     
     
    int 
    immissione () 
    {
      
     
     
    int n;
      
     
    int i;
      
     
    char invio;
      
     
     
      do
        
        {
          
     
    printf ("\nQuanti caratteri desideri inserire? ");
          
     
    scanf ("%d", &n);
        
     
    }
      
     
    while (n < 1 || n > MAX_C);
      
     
     
    for (i = 0; i < n; i++)
        
        {
          
     
    printf ("\nInserisci %d° carattere: ", i + 1);
          
     
    scanf ("%c", &invio);
          
     
    scanf ("%c", &V[i]);
        
     
    }
      
     
     
    return n;
    
     
    }
    
    
     
     
     
    void 
    stampa (int numeroElementi) 
    {
      
     
    int i;
      
     
    for (i = 0; i < numeroElementi; i++)
        
        {
          
     
    printf ("\nIl %d° carattere e': %c\n", i + 1, V[i]);
        
     
    }
    
     
    }
    
    
     
     
     
    void 
    stampaElemento (int posizione, int numeroElementi) 
    {
      
     
    if (posizione >= 0 && posizione < numeroElementi)
        
     
    printf ("\nLa poszione %d e' occupata dall'elemento %c\n", posizione,
    	       
    V[posizione]);
      
     
      else
        
     
    printf ("\nScegli una posizione esistente!\n");
    
     
    }
    
    
     
    void 
    
    stampaInversa (int numeroElementi) 
    {
      
     
    int i;
      
     
    for (i = numeroElementi - 1; i >= 0; i--)
        
        {
          
     
    printf ("\nIl %d° carattere e': %c\n", i + 1, V[i]);
        
     
    }
    
     
    }
    
  • Re: [C] Array di caratteri

    Molto meglio!
    Un consiglio: non usare mai
    
    if (condizione) then
        comando_true;
    else
      comando_false;
    
    preferisci sempre la versione con {}, anche per un comando singolo e semplice. È una fonte di possibili errori, difficili da rintracciare.
    Quando chiudi un blocco case o while è utile indicarlo, es:
    
        } //case
      } //while
    
    Al compilatore non gliene frega niente ma a te si...
  • Re: [C] Array di caratteri

    nicolap ha scritto:


    Molto meglio!
    Un consiglio: non usare mai
    
    if (condizione) then
        comando_true;
    else
      comando_false;
    
    preferisci sempre la versione con {}, anche per un comando singolo e semplice. È una fonte di possibili errori, difficili da rintracciare.
    Quando chiudi un blocco case o while è utile indicarlo, es:
    
        } //case
      } //while
    
    Al compilatore non gliene frega niente ma a te si...
    Ti ringrazio molto per i consigli!

    Il tuo sprono a fare meglio mi ha motivato, se completo interamente la traccia posso postarla qui oppure apro una nuova discussione?
  • Re: [C] Array di caratteri

    Continua qui.
  • Re: [C] Array di caratteri

    Ciao, mi sono bloccato al punto 5.

    Non ho capito esattamente cosa richiede.

    Avevo pensato di creare un nuovo vettore dove mettere i caratteri del vettore V più i primi tre dello stesso vettore.

    Avevo pensato, inoltre, di fare questo mediante un ciclo, ma essendo un array di caratteri non so come fare per terminarlo. Cioè, se fosse stata una stringa, avrei potuto dire di continuare fino al carattere speciale '\0', ma qui non so come comportarmi...

    La mia idea era una cosa del genere;
    
    
    int i = 0;
    
    char SecondoVettore [MAX_C];
    
    while ( V[i] != '\0' ) {
    
    SecondoVettore[i] = V[i];
    
    i++;
    
    } // while
    
  • Re: [C] Array di caratteri

    Ho provato a fare in questo modo.

    Ho realizzato questa funzione qui che aggiunge al vettore V i primi tre caratteri dello stesso vettore
      
     void 
     copiaPrimiTreCaratteri (int numeroElementi)
      {
      
      int i;
    
      for (i = 0; i <= 2; i++) 
      {
      
        V[numeroElementi + i] = V[i];
        
      }
      
    }
    
    A questo punto devo solo pensare a come usare la funzione che stampa l'elemento j-esimo per stampare un elemento di questo vettore "modificato"
  • Re: [C] Array di caratteri

    leo95nf ha scritto:


    Ciao, mi sono bloccato al punto 5.
    Testo:
    
    5. una funzione capace di costruire un vettore di caratteri costituito 
                                          (1)
                                          
    da tutti gli elementi di un vettore dato in input, 
                                                                 (2)
    
    e in aggiunta i primi 3 caratteri del vettore di in input stesso;
           (3)
    
    Bisogna sempre fare una accurata analisi lessicale del testo.
    Alcuni spunti:
    1) la "costruzione" può essere statica o dinamica, dipende se avete già studiato l'allocazione della memoria. In quest'ultimo caso, secondo me, l'allocazione DEVE essere dinamica, altrimenti l'esercizio perde molto.
    Poiché hai una "funzione" e il "costruire", il vettore dovrà essere restituito al chiamante che lo userà per il successivo punto 9.

    2) "input" può essere fuorviante: in qualche caso sarà l'input utente, in altri semplicemente il parametro passato alla funzione. Devi pensarci su e capire quale sia il caso!

    3) l'esercizio sembra particolarmente idiota ma nasconde un tranello (ovviamente): cosa succede se l'utente aveva inserito come numero di caratteri MAC_X? Out of Bound error!

    La funzione copiaPrimiTreCaratteri è sballata, buttala e ricomincia!
  • Re: [C] Array di caratteri

    leo95nf ha scritto:


      
      for (i = 0; i <= 2; i++) 
    
    Abituati a non usare MAI costanti.
    Sono ammessi 0 e 1, il 2 e il 10 solo quando rappresentano la base numerica.
    Tutto il resto DEVE essere dichiarato come "costante simbolica".
    Idem per le stringhe e i caratteri.

    Pensaci: stavi pensando al 3 ma hai scritto 2...
  • Re: [C] Array di caratteri

    nicolap ha scritto:


    Testo:
    
    5. una funzione capace di costruire un vettore di caratteri costituito 
                                          (1)
                                          
    da tutti gli elementi di un vettore dato in input, 
                                                                 (2)
    
    e in aggiunta i primi 3 caratteri del vettore di in input stesso;
           (3)
    
    Bisogna sempre fare una accurata analisi lessicale del testo.
    Alcuni spunti:
    1) la "costruzione" può essere statica o dinamica, dipende se avete già studiato l'allocazione della memoria. In quest'ultimo caso, secondo me, l'allocazione DEVE essere dinamica, altrimenti l'esercizio perde molto.
    Poiché hai una "funzione" e il "costruire", il vettore dovrà essere restituito al chiamante che lo userà per il successivo punto 9.

    2) "input" può essere fuorviante: in qualche caso sarà l'input utente, in altri semplicemente il parametro passato alla funzione. Devi pensarci su e capire quale sia il caso!

    3) l'esercizio sembra particolarmente idiota ma nasconde un tranello (ovviamente): cosa succede se l'utente aveva inserito come numero di caratteri MAC_X? Out of Bound error!

    La funzione copiaPrimiTreCaratteri è sballata, buttala e ricomincia!
    Ok, buttata!

    No, ho studiato solo l'allocazione statica, è un corso molto basilare!

    Ora ci ragiono su!
  • Re: [C] Array di caratteri

    #include <stdio.h>
    #define MAX_C 100		// Il masssimo numero di caratteri modificabile in base alle esigenze.
    
     char V[MAX_C];
     
    
    void gestioneSequenza (void);	// Gestisce il menu' e la scelta dell'utente.
    int immissione (void);		// Riempie il vettore con i caratteri.
    void stampaElemento (int numeroElementi, int posizione, int caratteriDaCopiare);	// Stampa l'elemento alla posizione
                                                                                           // j-esima indicata dall'utente.
    void stampa (int numeroElementi);	//Stampa il vettore.
    void stampaInversa (int numeroElementi);	//Stampa il vettore in maniera inversa.
    void copiaCaratteri (int numeroElementi, int caratteriDaCopiare);    //Copia i primi 'n' caratteri in coda al vettore V, con 'n' scelto dall'utente.
    
    int 
    main () 
    {
      
     
     gestioneSequenza ();	//Il main richiama semplicemente la funzione gestioneSequenza.
    } 
     
    void 
    
    
    gestioneSequenza () 
    {
      
     
     int numeroElementi;
      
     
     int scelta = -1;
      
     
     int posizione;
    
     int caratteriDaCopiare = 0;   // Inizializzo questa variabile a zero così la funzione 
                                  //stampaElemento all'inizio ha solo il numero di elementi del vettore V non modificato.
      
     
     
     while (scelta != 0)
        
        {
          
     
     
       printf ("\n***** MENU' *****");
          
     
       printf ("\n1. Immissione caratteri e stampa rovescia.\n");
          
     
       printf ("\n2. Stampa array di caratteri.\n");
          
     
       printf ("\n3. Stampa elemento.\n");
    
    
       printf ("\n4. Aggiungi caratteri.\n");
          
     
       printf ("\n0. Fine\n");
          
     
       printf ("***** FINE MENU' *****\n");
          
     
     
       printf ("\nScegli un'opzione dal menu': ");
          
     
       scanf ("%d", &scelta);
          
     
     
       switch (scelta)
    	
    	  {
    	
     
          case 1:
    	  
         numeroElementi = immissione ();	                    //Il numero di elementi viene reso noto a tutte le funzioni.
    	   stampaInversa (numeroElementi);
    	  
     
         break;
    	
     
         case 2:
    	  
         stampa (numeroElementi);
    	  
     
         break;
    	
     
         case 3:
    	  
         printf ("\nInserisci posizione da stampare: ");
    	  
     
         scanf ("%d", &posizione);
    	  
     
         stampaElemento (posizione, numeroElementi, caratteriDaCopiare);
    	  
     
         break;
    
    
         case 4:
    
         printf ("\nQuanti caratteri del vettore 'V' desideri aggiungere? ");
    
    
         scanf ("%d", &caratteriDaCopiare);
         
         
         printf ("\nFatto!\n);
    
    
         copiaCaratteri (numeroElementi, caratteriDaCopiare);
    
    
         break;
    	
     
        }   //case
        
     
       }   //while
    
     
    }
    
    
     
     
     
    int 
    immissione () 
    {
      
     
     
     int n;
      
     
     int i;
      
     
     char invio;
      
     
     
      do
        
      {
          
     
       printf ("\nQuanti caratteri desideri inserire? ");
          
     
       scanf ("%d", &n);
        
     
       }
      
     
     while (n < 1 || n > MAX_C);
      
     
     
     for (i = 0; i < n; i++)
        
      {
          
     
       printf ("\nInserisci %d° carattere: ", i + 1);
          
     
       scanf ("%c", &invio);
          
     
       scanf ("%c", &V[i]);
        
     
       }
      
     
     return n;
    
     }
     
    
    void 
    stampa (int numeroElementi) 
    {
      
     
     int i;
      
     
     for (i = 0; i < numeroElementi; i++)
        
      {
          
     
       printf ("\nIl %d° carattere e': %c\n", i + 1, V[i]);
        
     
       }
    
     
    }
    
    
     
     
     
    void 
    stampaElemento (int posizione, int numeroElementi, int caratteriDaCopiare) 
     {
      
     
     if (posizione >= 0 && posizione < numeroElementi + caratteriDaCopiare)
       {   
     
     printf ("\nLa poszione %d e' occupata dall'elemento %c\n", posizione,
    	       
     V[posizione]);
    
    
    }
      
      else 
          {
              
      printf ("\nScegli una posizione esistente!\n");
    
    }
    
    
    
     }
      
    
     
    void 
    
    stampaInversa (int numeroElementi) 
    {
      
     
    int i;
      
     
    for (i = numeroElementi - 1; i >= 0; i--)
        
        {
          
     
    printf ("\nIl %d° carattere e': %c\n", i + 1, V[i]);
        
     
    }
    
     
    }
    
    void 
    
    copiaCaratteri (int numeroElementi, int caratteriDaCopiare) 
    {
     
    
     int i;
      
      for (i = 0; i < caratteriDaCopiare; i++) 
         
          {
    
    
    V[numeroElementi + i] = V[i];
      
      
      }
    
    
     }
    
    Sono riuscito a far così...
  • Re: [C] Array di caratteri

    Comunque questa traccia proprio non la comprendo, i punti successivi dicono di stampare gli elementi di una stringa e di visualizzare il numero di elementi di una stringa ma io sto lavorando su un array di caratteri, quindi senza il carattere NULL '\0'.

    Boh!
  • Re: [C] Array di caratteri

    Definisci (nel programma) cosa è una stringa! E trasforma il vettore in stringa (sempre stando attendo al numero di caratteri).

    La funzione "copiaCaratteri" è sbagliata, troppo. Rileggi attentamente la consegna. Metti un commento nella funzione che richiama il numero della consegna: aiuti te e, soprattutto, il prof!
Devi accedere o registrarti per scrivere nel forum
38 risposte