Array di stringhe dinamici

di il
10 risposte

Array di stringhe dinamici

Buona domenica a tutti. Ho fatto il seguente programma che prende un array di 5 stringhe, ne visualizza la lunghezza con strlen, e mi dà in output le stesse stringhe senza spazi. Il programma funziona perfettamente con il metodo dei puntatori e di una matrice bidimensionale di char. Ora vorrei fare lo stesso programma con l'uso della memoria dinamica. Ogni stringa ha una dimensione variabile e la memoria si deve adeguare alla dimensione di ciascuna stringa. Poi bisogna eliminare gli spazi vuoti e mostrare in output le stesse stringhe senza spazi. Il codice del programma fatto con i puntatori e una matrice è il seguente:

#include <iostream>

using namespace std;

int main ()
{
   char *p;
   char stringa[5][80];
   
   for (int i=0; i<5; i++)
   {
       cout << "Stringa " << i+1 << ": ";
       gets (stringa[i]);
   }
       cout << endl;
   
   for (int i=0; i<5; i++)
   {
       int j=strlen(stringa[i]);
       cout << "Lunghezza: " << j << endl;
   }
   
   for (int i=0; i<5; i++)
   {
       p=&stringa[i][0]; 
       cout << endl << "Stringa " << i+1 << " senza spazi: ";
          while (*p)
             if (*p==32)
             p++;
             else cout << *p++;
   }
   
   cout << endl << endl;   
   system ("PAUSE");
   return 0;
}
Ho provato a renderlo con new, ma il compilatore mi segnala un errore già dalla dichiarazione, cosa strana visto che mi sembra corretta.

#include <iostream>

using namespace std;

int main ()
{
    
    char *p=new char[5][80];
   
    for (int i=0; i<5; i++)
    {
       cout << "Stringa " << i+1 << ": ";
       gets (p[i]);
    }
       cout << endl;
   
    for (int i=0; i<5; i++)
    {
       int j=strlen(p[i]);
       cout << "Lunghezza: " << j << endl;
    }
   
   for (int i=0; i<5; i++)
   {
       p=&stringa[i][0]; 
       cout << endl << "Stringa " << i+1 << " senza spazi: ";
          while (*p)
             if (*p==32)
             p++;
             else cout << *p++;
   }
   
   cout << endl << endl;   
   system ("PAUSE");
   return 0;
}
P.S. Ovviamente vorrei capire anche come deallocare una matrice visto che sul mio libro non ci sono esempi significativi a riguardo. Grazie mille.

10 Risposte

  • Re: Array di stringhe dinamici

    Qui hai da fare molte + modifiche. Poi non capisco sei in C++ e mi usi il gets. Sai che esiste anche la classe string che fa tutte ste cose in modo automatico? cmq una correzione del tuo codice potrebbe essere questa:
    
    
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int main ()
    {
    
    	char **p = new char *[5];
    
    	char *temp = new char[80];
    	//stringa temporanea
    
    	for (int i=0; i<5; i++)
    	{
    		cout << "Stringa " << i+1 << ": ";
    		cin.getline(temp,80,'\n');
    		p[i] = new char[strlen(temp) + 1];
    		strcpy(p[i],temp);
    	}
    	cout << endl;
    
    	for (int i=0; i<5; i++)
    	{
    		int j=strlen(p[i]);
    		cout << "Lunghezza: " << j << endl;
    	}
    
    	for (int i=0; i<5; i++)
    	{
    		char *ptr = &(p[i][0]);
    		cout << endl << "Stringa " << i+1 << " senza spazi: ";
    		while (*ptr)
    		{
    			if ((*ptr) == 32)
    				ptr++;
    			else cout << *ptr++;
    		}
    	}
    
    	for (int i=0; i<5; i++)
    	{
    		delete [] p[i];
    	}
    
    	delete [] p;
    	delete [] temp;
    	cout << endl << endl;   
    	system ("PAUSE");
    	return 0;
    }
    
  • Re: Array di stringhe dinamici

    Il tuo programma IN C++ senza new, delete o robe strane
    
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <vector>
    using namespace std;
    
    int main ()
    {
    	
    	vector<string> p;
    	string temp;
    
    	for (int i=0; i<5; i++)
    	{
    		cout << "Stringa " << i+1 << ": ";
    		getline(cin,temp);
    		p.push_back(temp);
    	}
    	cout << endl;
    
    	for (int i=0; i<5; i++)
    	{
    		int j = p[i].length();
    		cout << "Lunghezza: " << j << endl;
    	}
    
    	for (int i=0; i<5; i++)
    	{
    		cout << endl << "Stringa " << i+1 << " senza spazi: ";
    		p[i].erase(remove(p[i].begin(),p[i].end(),' '),p[i].end());
    		cout << p[i];
    	}
    
    	cout << endl << endl;   
    	system ("PAUSE");
    	return 0;
    }
    
  • Re: Array di stringhe dinamici

    Grazie skynet. Onde evitare l'apertura di un altro thread, espongo qui un altro algoritmo che non mi riesce molto bene. In pratica dato un array di stringhe, devo scrivere un programma che legga una parola chiave da cercare all'interno della matrice di stringhe, e ne determini il numero di occorrenze. L'esercizio mi dice anche di utilizzare la funzione di libreria strstr. Io ho provato ad implementare questo algoritmo ma qualcosa non va a dovere. In sostanza se nella stringa c'è una sola occorrenza l'algoritmo funzione. Ad esempio:
    stringa 1: ciao come stai
    stringa 2: ora vado ciao
    Se io digito stringa da cercare: "ciao" mi restituisce effettivamente 2. Se invece la stessa parola da cercare è ripetuta più volte nella stessa stringa non la conta. Ad esempio
    stringa 1: ciao ciao ciao
    stringa 2: torno presto ciao
    se cerco "ciao" mi restituisce 2 e non 4! stessa cosa se la stringa risulta non spaziata ad esempio
    ciaociaociao mi restituisci 1 e non 3! Dov'è l'errore? Come al solito incollo il codice:
    
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    void leggi (char [][80], int num);
    void scrivi (char [][80], int num);
    
    int main ()
    {
       cout << "Quante stringhe vuoi inserire? ";
       int num;
       cin >> num;
       char stringa[num][80]; 
       
       leggi(stringa,num);
       cout << endl;
       scrivi(stringa,num);
       
       char *p; // puntatore che scorre lungo le varie stringhe
       
       char cerca[80]; // stringa da cercare
       cout << "Stringa da cercare: ";
       cin.getline (cerca, 80);
       
       int numero=0; // contatore per le occorrenze
       
       for (int i=0; i<num; i++)
       {
          p=&stringa[i][0]; 
          char *q=strstr(stringa[i],cerca);
               if (q!=NULL)
               {
                 numero++;
                 p++;
               }
       }
       cout << "Numero di occorrenze pari a: " << numero; 
       
       cout << endl << endl;   
       system ("PAUSE");
       return 0;
    }
    
    void leggi (char v[][80], int num) // Lettura delle num stringhe
    {
         for (int i=0; i<num; i++)
       {
           cout << "Stringa " << i+1 << ": ";
           cin.sync(); // Pulisce lo stream
           cin.getline(v[i],80);
       }
    }
    
    void scrivi (char v[][80], int num) // Scrittura delle num stringhe
    {
         for (int i=0; i<num; i++)
       {
           cout << "Stringa " << i+1 << ": ";
           cout << v[i] << endl;
       }
    }
    
  • Re: Array di stringhe dinamici

    Una volta trovata una stringa con strstr dovresti solo incrementare il puntatore di inizio stringa e rifare la ricerca finchè non ne trova altre.
    
    for (int i=0; i<num; i++)
       {
         for(j = 0; j < strlen(stringa[i]); j++)
    {
          p=&stringa[i][j];
          char *q=strstr(p,cerca);
               if (q!=NULL)
               {
                 numero++;
                 p++;
               }
    }
       }
    
    una cosa così insomma. non ho provato il codice quindi verifica l'esattezza.
  • Re: Array di stringhe dinamici

    Non funziona..Ora provo a capire come mai, anche se dall'output che mi dà quando inserisco più parole nella stesse stringa, pare che conti tutti i caratteri e non la stringa per intero.
  • Re: Array di stringhe dinamici

    Oops l'ho visto adesso sta roba:
    
    cout << "Quante stringhe vuoi inserire? ";
       int num;
       cin >> num;
       char stringa[num][80];  //questo non è C++ valido
    
    vedi la dichiarazione dell'array di stringhe. Se usi gcc (incluso in Code::Blocks) questo codice può essere compilato ma NON è un codice valido. Il compilatore dovrebbe sapere a tempo di compilazione quanto spazio creare per la variabile e non in runtime. Per il resto dammi un pò di tempo che controllo.
  • Re: Array di stringhe dinamici

    Uso Dev-Cpp...Ma pare strano, perchè studiando dal libro di aguilar mi dice che la dimensione più a sinistra può essere una variabile, come nel mio caso.
  • Re: Array di stringhe dinamici

    Num non è const quindi non si sa a priori quanto spazio allocare sullo stack per la variabile.
    Il mio compilatore (Visual C++ 2008) mi da:
    
    error C2057: expected constant expression
    error C2466: cannot allocate an array of constant size 0
    error C2133: 'stringa' : unknown size
    
  • Re: Array di stringhe dinamici

    http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.htm
    http://en.wikipedia.org/wiki/Variable-length_arra

    E' una implementazione inserita nello standard C99 ma non tutti i compilatori lo supportano quindi non fare affidamento.
    E' valida solo per il C e non per il C++ per quello dico di non fare il mix tra i due linguaggi.
  • Re: Array di stringhe dinamici

    Scusa Paccio ti facio sta domanda:
    Perche impari/usi funzioni del C (quale strstr) se stai imparando il C++. Se il tuo libro spiega le cose in quel modo e il caso di buttarlo via e di usare un altro libro che spiega il C++ oppure prendere uno che spiega il C. I linguaggi sono 2, fare un mix dei due viene fuori un casino. La classe string (assieme alla classe vector) del C++ è una delle classi + potenti e semplici da usare, perche vi ostinate ad usare sempre il char* del C?
Devi accedere o registrarti per scrivere nel forum
10 risposte