Riconoscimento stringa:

di il
6 risposte

Riconoscimento stringa:

Salve ragazzi!
Stavo progettando un programma, però purtroppo non sono riuscito ad implementare bene una funzione. Quello che scriverò sarà una porzione del programma vero e proprio, quella che m'interessa, perché tutto il resto funziona. Il programma richiede di inserire un numero di persone indicando nome e cognome e, una volta inserito un cognome qualsiasi, tramite la funzione, bisogna verificare se sia uguale ad uno di quelli che appartengono alle persone inserite e se è così, indicare il numero della persona:


// Inserimento persone : 
#include <iostream>
using namespace std;

typedef struct pers { 
    char Nome[20];
    char Cognome[20];
    
} persona;

void ricerca_cognome(int N, persona dati[], int I, char Cogn[]) {
    for(int I = 0; I < N; I++) {
        if(dati[I].Cognome == Cogn){
            cout << "persona " << I+1 << endl;
        }
    }
}

int main () {
    int i;
    int n;
    int c;
    
    cout << "Inserire numero di persone : ";
    cin >> n;
    pers s[ n ];
    for ( i=0; i<n; ++i) {
        
        
        cout << "Per la persona numero " << i+1 << ":" << endl;
        cout << "Nome : ";
        cin >> s[i].Nome;
        cout << "Cognome : ";
        cin >> s[i].Cognome;
       
    }
    
    char surname[20];
    cout << "Inserisci un cognome : ";
    cin >> surname;
       
    ricerca_cognome (n, s, i, surname);
        
}
   
Ho un problema appunto con la funzione ricerca_cognome. Non riesco a capire dove sia l'errore. Il programma funge, ma quando inserisco il cognome, non me lo associa a quello delle persone.

Comunque scusatemi tantissimo se qualcuno avrà visto all'inzio il programma scritto non all'interno del riquadro apposito, ma purtroppo sono nuovo e non sapevo dove si trovasse la sezione in cui era spiegato come inserire tale riquadro.

6 Risposte

  • Re: Riconoscimento stringa:

    Non capisco come possa compilare senza avvertirti che stai dichiarando una variabile nel corpo della funzione che è già dichiarata tra gli argomenti.
    if(dati[I].Cognome == Cogn)
    Stai utilizzando una classe con un overload dell'operatore == che ti permette di verificare l'uguaglianza tra due stringhe?
  • Re: Riconoscimento stringa:

    Ciao, innanzitutto vorrei fare alcune considerazioni sul codice:
    - quale dovrebbe essere l'utilità di quel typedef?
    - perché passi l'argomento i alla funzione ricerca_cognome()?
    - lo standard del C++ prevede che la dimensione degli array (statici) sia una costante, ma quando dichiari l'array s la sua dimensione n è una variabile. Se non hai ancora studiato l'allocazione dinamica della memoria, una soluzione potrebbe essere quella di dichiarare un array di N (che è una costante) elementi e considerarne poi solo i primi n<=N (dove n può essere anche una variabile).

    Veniamo ora al motivo per cui la funzione non funziona (scusa per il gioco di parole ). Il problema è nella seguente condizione:
    dati[j].Cognome == Cogn
    L'identificatore di un array (e quindi anche di una stringa c-style), salvo rare eccezioni, decade a puntatore al suo primo elemento. Questo è quello che accade anche nella precedente riga di codice, praticamente con quel == stai chiedendo se l'indirizzo di memoria del primo carattere della stringa dati[j].Cognome sia uguale all'indirizzo di memoria del primo carattere della stringa Cogn, cosa ovviamente impossibile per due stringhe distinte (a prescindere dal loro contenuto).
    Forse ti sei fatto ingannare anche dal fatto che cin>>str e cout<<str consentono di leggere e stampare una stringa; questo comportamento in realtà si spiega con l'overload degli operatori, ma lascia stare per il momento perchè credo sia un argomento che non hai ancora affrontato.
    Per curiosità, come fai a verificare l'uguaglianza tra due vettori di interi u e v? Scrivi u==v oppure verifichi l'uguaglianza tra i relativi elementi?
  • Re: Riconoscimento stringa:

    Ti ringrazio moltissimo della risposta, ma, non voglio fare brutta figura, credici o meno, noi all'università non abbiamo studiato le classi, ora che le sono andate a cercare ed ho visto cosa sono. Figurati che non abbiamo nemmeno studiato l'utilizzo dei puntatori nelle funzioni. Io faccio parte del ramo di ingegneria industriale, motivo per cui il nostro programma è abbastanza ristretto e dobbiamo arrangiarci con quello che ci viene insegnato. Come puoi vedere abbiamo fatto strutture, array, stringhe, funzioni, anche di diversi tipi, come le ricorsive, ma le classi, nè tantomeno l'overload, non li abbiamo mai usati. Ti chiedo ancora scusa, ma quindi non c'è un altro per stabilire l'uguaglianza utilizzando le nozioni che ti ho appeno riferito aver studiato? Comunque no, non mi dà errore stranamente. Il programma va. Tra l'altro sono rimasto abbastanza stupito, perché la seguente funzione, appartenente ad un programma precedente che deve stampare gli studenti con voto più alto di quello inserito da tastiera, è scritta in modo simile e funge bene:
    
    
    // Inserimento studenti : 
    #include <iostream>
    using namespace std;
    
     struct stud { 
        char Nome[20];
        char Cognome[20];
        int Matricola;
        int Voto;
        
    } ;
    
    
    
    
    void visualizza_voto (int T, struct stud cerca[], int k, int r) {
        
        if (r<cerca[k].Voto) {
        
        cout << "Studente " << k+1 << endl;
        }
        
    }
    
    
    
    
    int main () {
        int i;
        int n;
        int c;
        
        cout << "Inserire numero di studenti : ";
        cin >> n;
        stud s[n];
        for (int i=0; i<n; ++i) {
            
            
            cout << "Per lo studente numero " << i+1 << ":" << endl;
            cout << "Nome : ";
            cin >> s[i].Nome;
            cout << "Cognome : ";
            cin >> s[i].Cognome;
            cout << "Matricola : ";
            cin >> s[i].Matricola;
            cout << "Voto : ";
            cin >> s[i].Voto;
        }
         
        
        
        int p;
        cout << "Inserisci un voto : ";
        cin >> p;
        
        cout << "Gli studenti che hanno avuto un voto maggiore di " << p << " sono : ";
        
        for (int i=0; i<n; ++i) {
        
        visualizza_voto (n, s, i, p);
        }
      
      
      
        
       
    }
    
    
    forse è stata una situazione fortuita, o molto più probabilmente mi sfugge qualcosa, potresti aiutarmi?
  • Re: Riconoscimento stringa:

    Nippolo ha scritto:


    Ciao, innanzitutto vorrei fare alcune considerazioni sul codice:
    - quale dovrebbe essere l'utilità di quel typedef?
    - perché passi l'argomento i alla funzione ricerca_cognome()?
    - lo standard del C++ prevede che la dimensione degli array (statici) sia una costante, ma quando dichiari l'array s la sua dimensione n è una variabile. Se non hai ancora studiato l'allocazione dinamica della memoria, una soluzione potrebbe essere quella di dichiarare un array di N (che è una costante) elementi e considerarne poi solo i primi n<=N (dove n può essere anche una variabile).

    Veniamo ora al motivo per cui la funzione non funziona (scusa per il gioco di parole ). Il problema è nella seguente condizione:
    dati[j].Cognome == Cogn
    L'identificatore di un array (e quindi anche di una stringa c-style), salvo rare eccezioni, decade a puntatore al suo primo elemento. Questo è quello che accade anche nella precedente riga di codice, praticamente con quel == stai chiedendo se l'indirizzo di memoria del primo carattere della stringa dati[j].Cognome sia uguale all'indirizzo di memoria del primo carattere della stringa Cogn, cosa ovviamente impossibile per due stringhe distinte (a prescindere dal loro contenuto).
    Forse ti sei fatto ingannare anche dal fatto che cin>>str e cout<<str consentono di leggere e stampare una stringa; questo comportamento in realtà si spiega con l'overload degli operatori, ma lascia stare per il momento perchè credo sia un argomento che non hai ancora affrontato.
    Per curiosità, come fai a verificare l'uguaglianza tra due vettori di interi u e v? Scrivi u==v oppure verifichi l'uguaglianza tra i relativi elementi?
    Ringrazio molto anche te! Rispondendo alla tua ultima domanda, verifico che ogni singolo elemento sia uguale. Nel caso di una stringa, attraverso un ciclo for metto in relazione ogni lettera della prima parola con la seconda... E INFATTI HO CAPITO ORA! FUNZIONA! (l'entusiasmo parte da qui, perché è da questo punto che mi accorgo di tutto XD XD )Praticamente ho riscritto così:
    
    if(dati[I].Cognome[I] == Cogn[I])
    
    e mi trovo! Perdonami ancora, è vero! Mi è sfuggito questo dettaglio non da poco. Tra l'altro, ho risposto anche all'altro utente, è questo il motivo per cui quella funzione che confronta i voti degli studenti, funziona invece? Perché in quel caso si confrontano numeri e non array, o vettori, o stringhe?
    Comunque, al fine di rendere il programma più pulito, potresti poi consigliarmi come scriverlo in maniera migliore seguendo i punti che mi hai segnalato all'inzio? GRAZIE INFINITE ANCORA! Purtroppo quando andavo alle lezioni potevo seguire poco e nulla d'informatica, essendo impegnato già con altri esami e quindi ho dovuto studiare tutto da solo e così sto perdendo parecchi elementi importanti lungo la strada.
  • Re: Riconoscimento stringa:

    Magari prova prima ad applicare in maniera autonoma i vari suggerimenti che ti sono stati forniti e posta il codice aggiornato.

    P.S.
    Non so se fa parte del tuo corso di studi, ma esiste una libreria apposita che opera sulle stringhe C-style (cstring in C++), che tra le varie cose contiene anche una funzione (strcmp()) per il confronto delle stringhe.
  • Re: Riconoscimento stringa:

    Ah sì sì. In un altro appello d'esame dovevamo proprio utilizzare come funzioni strncpy, strcat, ecc. Si deve inserire la libreria <string.h>. C'è pure la funzione per il confronto.... ecco, potevo utilizzare quella è non ci ho nemmeno pensato, mannaggia a me! Comunque sì, magari riposterò il programma scrivendolo in una maniera migliore. Mille grazie ancora!!!
Devi accedere o registrarti per scrivere nel forum
6 risposte