Programma rimozione caratteri, errore

di il
6 risposte

Programma rimozione caratteri, errore

Sto scrivendo un programma che rimuova tutti i caratteri dalla stringa s1 che sono presenti nella s2, ecco il codice:
#include <stdio.h>
#define MAXCHAR 50
void squeeze(char s1[],char s2[], char s3[])
{
    int i,j,k;
    char sp[MAXCHAR];
    for(j=0;s2[j]!='\0'&& j<MAXCHAR-1;j++)
    {
        for(i=k=0;s1[i]!='\0' && i<MAXCHAR-1;i++) 
        {
            if(s1[i]!=s2[j])    
                sp[k++]=s1[i];
        }
        if  (s1[i]=='\0')
            sp[k++]=s1[i];
        for (i=0;sp[i]!='\0' && i<MAXCHAR-1;i++)
            s1[i]=sp[i];
        if  (sp[i]=='\0')
            s1[i++]=sp[i];
    }
s3[i]="cc";
}
int main()
{
    char result[MAXCHAR];
    squeeze("ciao","ao",result);
    printf("%s",result);
    return 0;
}
dà errore nel ciclo for in squeeze() dove cerco di copiare sp in s1 (s1=sp)

6 Risposte

  • Re: Programma rimozione caratteri, errore

    Come dice il compilatore:
    D:\C_C++\CodeBlock\iop\main.c||In function 'squeeze':|
    D:\C_C++\CodeBlock\iop\main.c|32|warning: operation on 'i' may be undefined [-Wsequence-point]|
    D:\C_C++\CodeBlock\iop\main.c|35|warning: assignment makes integer from pointer without a cast
    Nella funzione "squeeze":
    attenzione,l'operazione alla variabile "i" è indefinita [sequenza]
    attenzione,assegni ad un integer un puntatore.

    --

    Per quanto riguarda il primo warning,che non sono errori:
    
        s1[i++]=sp[i];
    
    tale riga è indefinita tranne che non si conoscano a priori le decisioni del compilatore.
    i++ quando dovrebbe avvenire?
    tu vorresti che la locazione s1 = sp e poi ++i,ma il compilatore potrebbe incrementare i dopo la lettura di s1.
    Quindi è piu consignliabile:
    
    s1[i]=sp[i];
    ++i;
    
    
    //s3[i]="cc"; errato s3[i]==char "cc" == puntatore;
    s3[i++]='c';
    s3[i]='c';
    


    Giusto per simpatia:
    
    #define MAXCHAR 50
    void squeeze(char s1[],char s2[], char s3[])
    {
        unsigned int k1,k2,k3; //indici riferiti ai relavivi vettori
    
        for(k1=0,k3=0 ; s1[k1] != '\0' ;k1++)
        {
            for(k2=0; s2[k2] != '\0' ;k2++)
                if(s1[k1] == s2[k2])    break;
            
            if (s2[k2] == '\0') s3[k3++]=s1[k1];
        }
    
        s3[k3]='\0';
    
    }
    
    int main()
    {
        char a[] = "vbextreme";
        char b[] = "aeiou ";
        char result[MAXCHAR];
    
        squeeze(a,b,result);
    
        printf("%s",result);
    
        return 0;
    }
    
    
  • Re: Programma rimozione caratteri, errore

    come dice il compilatore:
    D:\C_C++\CodeBlock\iop\main.c||In function 'squeeze':|
    D:\C_C++\CodeBlock\iop\main.c|32|warning: operation on 'i' may be undefined [-Wsequence-point]|
    D:\C_C++\CodeBlock\iop\main.c|35|warning: assignment makes integer from pointer without a cast


    Nella funzione "squeeze":
    attenzione,l'operazione alla variabile "i" è indefinita [sequenza]
    che compilatore usi? code::blocks non mi dice nulla, sembra funzionare bene, quando lo eseguo però crasha...
    attenzione,assegni ad un integer un puntatore
    ancora non sono arrivato a studiare i puntatori purtroppo..
    tale riga è indefinita tranne che non si conoscano a priori le decisioni del compilatore.
    i++ quando dovrebbe avvenire?
    in questo caso non vale la regola x=i++ == x legge i prima dell'incremeno e invece x=++i == x legge i dopo lincremento?
    //s3="cc"; errato s3==char "cc" == puntatore;
    s3[i++]='c';
    s3='c';

    questa riga lasciamola stare, la dovevo cancellare, era solo una prova per vedere se crashava solo perchè dovevo ancora definire s3

    alla fine comunque mentre aspettavo una risposta continuavo a provarci ed ero arrivato alla soluzione:
    #include <stdio.h>
    #define MAXCHAR 50
    void squeeze(char s1[],char s2[], char s3[])
    {
        int i,j,k;
        char sp[MAXCHAR];
        for (i=0;s1[i]!='\0';i++)
                sp[i]=s1[i];
            if  (s1[i]=='\0')
                sp[i]=s1[i];
        for(j=0;s2[j]!='\0'&& j<MAXCHAR-1;j++)
        {
    
            for(i=k=0;sp[i]!='\0' && i<MAXCHAR-1;i++)
            {
                if(sp[i]!=s2[j])
                    sp[k++]=sp[i];
            }
            if  (sp[i]=='\0')
                sp[k++]=sp[i];
            for (i=0;sp[i]!='\0' && i<MAXCHAR-1;i++)
                s3[i]=sp[i];
            if  (sp[i]=='\0')
                s3[i++]=sp[i];
        }
    
    }
    int main()
    {
        char result[MAXCHAR];
        squeeze("stringa 1","stringa 2",result);
        printf("%s",result);
        return 0;
    }
    grazie comunque per la tua versione del codice , anche se non mi è del tutto chiara perchè essendo agli inizi ancora certi termini che hai usato del linguaggio C non li conosco ancora
  • Re: Programma rimozione caratteri, errore

    MingW 4.4.1
    Code::Block 12.11

    Premendo il tasto F2 ti appare una serie di tab in basso,clicca su "Build Message" li ci sono i messaggi del compilatore.

    Può darsi che non hai attivato i flags:
    Project->build option...->
    A sinistra c'è un albero clicca sulla radice (il nome del progetto).
    Controlla che sia selezionato Compiler Setting e la sottotab Compiler Flags.
    Bene ora cerca la riga: "Enable all compiler warning...[-Wall]" mettici la spunta,clicca su ok e fai rebuild oppure le doppie frecce circolari oppure ctrl+f11.

    Vai anche in:
    Setting->Compiler->
    Nei flags che vedi controlla che non ci sia niente di cliccato e salva.



    in questo caso non vale la regola x=i++ == x legge i prima dell'incremeno e invece x=++i == x legge i dopo lincremento?
    dipende dal compilatore e dalla situazione,infatti non ti da errore ma warning,ovvero attenzione.
    Devi essere sicuro,quindi è sempre meglio evitare i warning soprattutto chi è agli esordi come te.


    Che termini non hai capito? ho usato la dicitura piu elementare possibile.
  • Re: Programma rimozione caratteri, errore

    Mi sono accorto che quei warning li da solo se inserisco il file in un progetto, ecco perchè non li vedevo prima...
    per quanto riguarda il discorso della priorità dell'assegnazione quando è nella stessa espressione dove c'è un incremento ho appena iniziato a farlo, proprio perchè questo che ho fatto è il programma di esercizio dell capitolo di "il linguaggio C" dove spiegano questa cosa, cercavo di abituarmi per quando comincerò a fare programmi più complicati dove magari qualche riga in meno può fare le differenza..
    Ma se dici di evitare questa forma ti posso chiedere perchè nella tua versione del programma hai usato anche tu s3[k3++]=s1[k1], a te non dà il warning?
    Che termini non hai capito? ho usato la dicitura piu elementare possibile.
    in realtà è solo 1 il termine che non capisco: break
  • Re: Programma rimozione caratteri, errore

    mi sono accorto che quei warning li da solo se inserisco il file in un progetto, ecco perchè non li vedevo prima...
    Quando crei un nuovo programma è ovvio che crei un nuovo progetto....
    hai usato anche tu s3[k3++]=s1[k1], a te non dà il warning?
    Ecco forse non mi sono spiegato...
    io ho usato 2 variabili diverse.
    cerco di spiegarmi,il compilatore diciamo che crea un codice assembly,ora cerco di farti capire cosa possa accadere con dello pseudocode:

    codice:: A[i++]=B;
    il compilatore potrebbe fare:

    METTOIN eax,A;
    AGGIUNGO1 i;
    ASSEGNOVALORE eax,B;

    ma potrebbe anche fare:

    METTOIN eax,A;
    ASSEGNOVALORE eax,B;
    AGGIUNGO1 i;

    ma potrebbe fare anche in modo diverso,ovvero non è detto che i++ avvenga dopo l'assegnamento della variabile,potrebbe farlo anche in mezzo.
    Mentre se usi due variabili diverse il problema non sussiste perchè anche se modfico l'indice il valore assegnato non cambia.

    Come fai a conoscere i clicli senza conoscere il break e il continue?
    Break interrompe il ciclo.
    Continue esegue il sucessivo ciclo senza esaminare il codice:
    
    int i,k;
    for (i=0,k=0; i < 10; i++)
    {
        break;
        ++k;
    }
    
    in questo caso k==0 perchè appena entro nel ciclo esco con break.
    
    int i,k;
    for (i=0,k=0; i < 10; i++)
    {
        continue;
        ++k;
    }
    
    anche in questo caso k==0 perchè il continue passa al ciclo sucessivo senza analizzare il codice.

    un esempio anche se bruttino può essere:
    
    int i=-1;
    while (1) // ciclo infinito
    {
        i++;
        if (stringa[i] == 'a')
        {
            continue;
        }
        else if (stringa[i] == '\0')
        {
             stringaritorno[k]=stringa[i];
             break;
        }
        else
        {
            stringaritorno[k++]=stringa[i];
        }
    }
    
    anche se il codice è osceno si capisce che se trovo a salto tutto e rinizio il ciclo,se trovo fine stringa allora copio la fine ed esco altrimenti copio il carattere e avanzo il cursore.





    La prima cosa che ho fatto da neofita(come lo siamo stati tutti) è stato nello scrivere subito il codice,creando grandissimi casini.
    Poi ho imparato un trucco,prima scrivo in italiano quello che voglio fare,poi faccio un diagramma e alla fine il codice salta fuori da solo. E non scerzo!





    IT::La stringa R è la copia di A che non ha i caratteri di B.
    AVRò::
    
    Funzione (Stringa R, Stringa A, Stringa B)
        Per ogni carattere di Stringa A:
             Per ogni carattere di Stringa B: 
                  Controllo che non ci sia il carattere corrente di stringa A
             Sucessivo
             
             Se Il carattere di Stringa A non è in Stringa B Allora:
                 Stringa R=Stringa A,muovo stringa r
        
        Sucessivo
    Fine Funzione
    
    
    questo ovvio che è solo un esempio, tu devi trovare la tua strada,tradurre poi da italiano a c o altro linguaggio diventa una cosa superflua.
  • Re: Programma rimozione caratteri, errore

    Quando crei un nuovo programma è ovvio che crei un nuovo progetto....
    sì, ma dato che a quell'esercizio avevo già trovato la soluzione e dovevo solo controllare quei 2 warning avevo copiato dal forum il mio vecchio codice errato in un empty file e compilato, senza inserirlo in progetti, pensavo fosse lo stesso.. evidentemente no
    Mentre se usi due variabili diverse il problema non sussiste perchè anche se modfico l'indice il valore assegnato non cambia.
    chiarissimo, ora ho capito
    Come fai a conoscere i clicli senza conoscere il break e il continue?
    sto studiand il C da autodidatta, con l'aiuto solo del forum e seguendo passo passo il libro "il linguaggio C", è strutturato un po' stranamente, all'inizio ha dato una panoramica un po' a tutto, while, for, if, variabili, costanti..... e poi rivede tutto in dettaglio, pensa che alla pagina dove spiega il break ci sono arrivato ieri e ancora devo sentir parlare di continue, anche se ora, dopo la tua spiegazione lo saprei già usare..
    prima scrivo in italiano quello che voglio fare,poi faccio un diagramma e alla fine il codice salta fuori da solo. E non scerzo!
    non ci avevo mai pensato, questo aiuterà molto grazie
Devi accedere o registrarti per scrivere nel forum
6 risposte