[C] Cancellare elemento da vettore

floppyes
Ciao a tutti!

Devo risolvere questo esercizio:
Si sviluppi un programma in linguaggio C che, date le due stringhe (che si possono supporre già acquisite)
char caratteri[5];
char stringa[25];
elimini dalla seconda stringa tutti i caratteri presenti nella prima. Se una stringa occupa meno posizioni di quelle disponibili nel vettore (rispettivamente 5 e 25), si suppone che sia allineata a sinistra e che tutti i rimanenti posti liberi a destra siano occupati dal carattere zero.
Ad esempio, se caratteri=”pabab” e stringa=”pasta all’amatriciana0000” il programma deve modificare stringa in modo che risulti “st ll’mtricin000000000000”.


Ecco il codice che ho scritto io:
#include <stdio.h>

int main() 
{
    int i, j, s=0;
    char caratteri[5]={"pabab"};
    char stringa[25]={"pasta all'amatriciana0000"};
    char uscita[25];
    
    for (i=0;i<5;i++)
    {
        for (j=0;j<25;j++)
        {
            if (caratteri[i]==stringa[j])
            {
                for ( ; stringa[j+1]!='\0' ; j++)
                {
                    stringa[j]=stringa[j+1];
                }
            }
        }
    }
    
    for (i=0;i<25;i++)
    uscita[s]=0;
    
    for (j=0;stringa[j]!='\0';j++)
    {
        uscita[j]=stringa[j];
    }

    printf("%s", uscita);
        
    return 0;
    
}


Quello che non capisco è perchè si ferma dopo 5 caratteri e non continua fino alla fine del secondo vettore!
Infatti quando lo lancio ottengo come output:
st all'amatriciana0000000


Grazie mille
Ciaoo :)

Risposte
Summerwind78
Ciao

devo dire che sto faticando a capire dove sia il problema del tuo codice.

Peró ne ho scritto uno mio e sembra andare, dimmi se ti piace


#include <stdio.h>
#define TRUE 1
#define FALSE 0

unsigned char ElementoInArray(unsigned char elemento, unsigned char* myArray, unsigned char arraySize){

unsigned char i;

    for (i=0; i<arraySize; i++){
        if (myArray[i] == elemento) return TRUE;
    }
    return FALSE;


}

int main()
{
    int i, s=0;
    unsigned char caratteri[5]= {"12345"};
    unsigned char stringa[25]= {"p12i3ppo00000000000000000"};
    unsigned char uscita[25];


    for (i=0;i<25;i++){
        uscita[i] = '\0';
     }

    for (i=0;i<25;i++){
        if(ElementoInArray(stringa[i], caratteri, 5) == FALSE)
             uscita[s++] = stringa[i];
   }
    printf("%s", uscita);

return 0;
}

floppyes
Ciao!

Si devo dire che è perfetto. Nel frattempo ho riscritto di nuovo il mio codice adottando un'altra via e funziona:
#include <stdio.h>

int main ()
{
    int i, j, s=0;
    char caratteri[] = "pabab";
    char stringa[] = "pasta all'amatriciana0000";
    char uscita[26];
    
    for (i=0;caratteri[i]!='\0';i++)
    {
        for (j=0;stringa[j]!='\0';j++)
        {
            if (stringa[j]==caratteri[i])
            stringa[j]='1';
        }
    }
    
    for (i=0;stringa[i]!='\0';i++)
    uscita[i]='0';
    
    for (i=0;stringa[i]!='\0';i++)
    {
        if (stringa[i]!='1')
        uscita[s++]=stringa[i];
    }
       
    for (i=0;uscita[i]!='\0';i++)
        printf("%c", uscita[i]);
    
    return 0;
}


Grazie mille per l'aiuto :)
Ciaoo!

vict85
@ summerwind78: Non è più necessario definire TRUE e FALSE: dal C99 è stato introdotto il tipo _Bool e delle macro apposite http://stackoverflow.com/questions/4767 ... -data-type (devi solo ricordarti di usare uno degli ultimi due standard. Comunque non era necessario usare dei bool.

--------------------------------------

Ma i caratteri che tu consideri sono necessariamente alfabetici oppure valgono anche spazi e cose così? Inoltre devi tener conto o meno della differenza tra lettere maiuscole e minuscole?

floppyes
Ciao!

Nel testo dell'esercizio non è specificato, l'unica cosa non si possono utilizzare le librerie per la gestione delle stringhe.

Comunque ho provato e gli spazio vengono eliminati, mentre le lettere se sono maiuscole non vengono eliminate. Comunque credo faccia riferimento solo a lettere minuscole.

In caso per convertire una lettera da maiuscola a minuscola devo utilizzare la codifica ascii giusto?

Ciao!

Summerwind78
"vict85":
@ summerwind78: Non è più necessario definire TRUE e FALSE: dal C99 è stato introdotto il tipo _Bool e delle macro apposite http://stackoverflow.com/questions/4767 ... -data-type (devi solo ricordarti di usare uno degli ultimi due standard. Comunque non era necessario usare dei bool.

I bool sono rimasti da una precedente prova che avevo fatto. Mi sono dimenticato di cancellarli

floppyes
Ciao a tutti!

Torno su questo argomento perchè non mi è chiara ancora una cosa! Se io ho un vettore e voglio eliminare un elemento da quel vettore, l'unico modo per farlo è utilizzare un'altro vettore dove copiare gli elementi diversi dal valore che voglio eliminare?

Mi spiego meglio:
Ho un vettore di grandezza 5 contenente i seguenti numeri: 0,1,2,3. Ho lasciato uno spazio vuoto in quanto il vettore deve avere il carattere di fine stringa \0.

All'interno di questo vettore voglio eliminare il numero 2. Allora dichiaro una variabile: eliminami=2 e poi con un ciclo for vado ad eliminare il numero e scalare tutti gli elementi del vettore.

Quello che non riesco a capire è come mai il ciclo non funziona:
#include <stdio.h>
#define DIM 5
int main ()
{
int vettore[DIM]={0,1,2,3};
int elimina=2, i,j;
for (i=0;i<DIM;i++)
{
if (vettore[i]==elimina)
{
for (j=i+1;j<DIM;j++)
{
vettore[i]=vettore[j];
}
}
}
for (i=0;i<DIM;i++)
{
printf("%4d", vettore[i]);
}
return 0;
}

La domanda è: si può eliminare un valore da un array e far scalare tutti gli elementi di una posizione (compreso il carattere di fine stringa \0) utilizzando lo stesso vettore e non un secondo vettore per la copia?

Sul libro del professore ho trovato questo codice:
int f(int v[], int n, int num)
{
int i, j;
for (i = 0; i < n; i++)
{
if (v[i] <= num)
{
break;
}
}
if (v[i] == num)
{
for (j = i; j < n - 1; j++)
{
v[j] = v[j + 1];
return n - 1;
}
}
else return n;
}


E' una funzione che cancella un dato intero x in una data sequenza di n interi disposti in ordine decrescente, mantenendo l’ordinamento e producendo la nuova lunghezza della sequenza.

In teoria dovrebbe essere la soluzione al mio problema, ma non riesco a capire come funziona!

Se riuscite a farmi luce su questo punto, ho guardato anche il manuale ma non fanno nessun esempio del genere! A me interessa capire come cancellare l'elemento voluto e spostare gli altri al suo posto

Grazie mille in anticipo!
Ciaoo :-)

vict85
Non è affatto necessario. Comunque se hai un vettore di int non si usa il terminatore di stringhe.
In generale si può anche fare in-place:
int j = 0;
for(int i=0; i<size; ++i)
{
if(condizione sull'elemento di indice i)
{
v[j] = v[i];
++j;
}
}
for(;j <size; ++j)
{
v[j] = 0;
}

dove ho supposto che si azzerassero gli elementi successivi.

floppyes
Ciao vict85!

Grazie mille era proprio quello che cercavo, ho dovuto solo modificare metterndo:
v[j]!=v[i];

In questo modo elimino il numero e scalo il vettore tutto di uno!
Ecco il codice del programma:
#include <stdio.h>
#define size 6
int main ()
{
    int j=0,i;
    int v[]={0,1,2,3,4,5};
    int elimina=2;
    
    for(i=0; i<size; ++i)
    {
        if(v[i]!=elimina)
        {
            v[j] = v[i];
            ++j;
        }
    }
    for(;j <size; ++j)
    {
        v[j] = 0;
    }
    for (i=0;i<size;i++)
    printf("%d", v[i]);
    return 0;
}

Così funziona tutto! Inoltre ho tolto il valore di fine stringa, in effetti non andava utilizzato!

Grazie
Ciaoo!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.