Sottostringhe in C

di il
11 risposte

Sottostringhe in C

Ciao a tutti.
Allora ho un problema semplicissimo su cui mi sto incaponendo e riguarda le stringhe in C.

Dovrei,prese le stringhe s1 e s2 creare una terza stringa s3 lunga come s1 e che ha il carattere s1(i-esima) al posto s3(i-esima) se il carattere s1(i-esima) si trova in s2 in alternativa alla posizione s3(i-esima) bisogna mettere '-'.
Per esempio
s1 = "catrame"
s2 = "tre"
s3 = "--tr--e"

la funzione che ho ipotizzato è più o meno questa.


char* eliminazione(char s1[], char s2[]){
	unsigned long int len = strlen(s1);
	char* s3 = (char*)malloc(len*sizeof(char));
	for (int i = 0; i < len; i++){
		if (strstr(s2, s1[i]) != NULL){             // strstr dovrebbe trovarmi se la sottostringa s1[i] è contenuta in s2
			s3[i] = s1[i];
		}else{
			s3[i] = '-';
		}
	}
	return s3;
}
Ovviamente non va...
Grazie mille a tutti.

11 Risposte

  • Re: Sottostringhe in C

    Ciao, ma a te compila? La funzione strstr() si aspetta come argomenti due stringhe, invece tu gli passi una stringa e un char.
    In ogni caso visto che non stai cercando una sottostringa, ma un semplice carattere, dovresti utilizzare la funzione strchr().

    Inoltre attento che prima del return manca un passaggio fondamentale affinché s3 sia considerata una stringa e non un semplice array di char!
  • Re: Sottostringhe in C

    Nippolo ha scritto:


    Ciao, ma a te compila? La funzione strstr() si aspetta come argomenti due stringhe, invece tu gli passi una stringa e un char.
    In ogni caso visto che non stai cercando una sottostringa, ma un semplice carattere, dovresti utilizzare la funzione strchr().
    Si compilava ma il risultato era semplicemente una serie di trattini lunghi come s1.
    Inoltre attento che prima del return manca un passaggio fondamentale affinché s3 sia considerata una stringa e non un semplice array di char!
    Hai ragione devo mette '/0' come teminatore di stringa. Ma serve davvero?!? Perché ho scritto varie funzioni che modificano dei form di testo, e ho dimenticato la nozione, ma ogni volta che invocavo la printf con il label %s che indica la stringa non ho mai avuto problemi.
    Semplice fortuna o c'è una spiegazione più concreta?
  • Re: Sottostringhe in C

    EdNigma ha scritto:


    Si compilava ma il risultato era semplicemente una serie di trattini lunghi come s1.
    Strano che compilava...

    EdNigma ha scritto:


    Hai ragione devo mette '/0' come teminatore di stringa. Ma serve davvero?!?
    Secondo te come fa per esempio la funzione strlen(char*) a svolgere il proprio compito senza conoscere la dimensione dell'array?

    EdNigma ha scritto:


    Perché ho scritto varie funzioni che modificano dei form di testo, e ho dimenticato la nozione, ma ogni volta che invocavo la printf con il label %s che indica la stringa non ho mai avuto problemi.
    Semplice fortuna o c'è una spiegazione più concreta?
    Fortuna che c'era un \0 al posto giusto!

    P.S.
    Ho appena notato che c'è un altro errore nella funzione... indizio: cosa ritorna la funzione strlen()?
  • Re: Sottostringhe in C

    Secondo te come fa per esempio la funzione strlen(char*) a svolgere il proprio compito senza conoscere la dimensione dell'array?
    Assolutamente, '/0' indica la terminazione della stringa. Solo che mi sembrava strano che alcune cose funzionassero senza che inserissi '/0', pensavo che non mi compilasse o addirittura le funzioni di I/O mi andassero a leggere fuori dai limiti. Sicuramente come ben dici è fortuna.
    P.S.
    Ho appena notato che c'è un altro errore nella funzione... indizio: cosa ritorna la funzione strlen()?
    strlen() da di ritorno un long int, ho segnato unsigned. Pensando che la lunghezza non può essere < 0. Una precisazione forse futile.

    Comunque grazie, ora funziona. Purtroppo venendo dal python lavorare con le stringhe è un pochino diverso.
  • Re: Sottostringhe in C

    EdNigma ha scritto:


    strlen() da di ritorno un long int, ho segnato unsigned. Pensando che la lunghezza non può essere < 0. Una precisazione forse futile.
    Mi riferivo a qualcosa di molto più pratico, strlen() ritorna la lunghezza della stringa senza contare il carattere terminatore, quindi la riga con la malloc() va aggiustata.
  • Re: Sottostringhe in C

    Mi riferivo a qualcosa di molto più pratico, strlen() ritorna la lunghezza della stringa senza contare il carattere terminatore, quindi la riga con la malloc() va aggiustata.
    Hai ragione. Posso porti un quesito allora?
    Prendiamo questo codice che ho scritto cosi per prova.
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <stdbool.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
    
    
    int main(int argc, char** argv){
    	char* s1 = "casa\0";
    	unsigned long int len1 = strlen(s1);
    	printf("Prova 1. ");
    	for (int i = 0; i < len1; i++){
    		printf("%c", s1[i]);
    	}
    	printf("\nProva 2. ");
    	printf("%s", s1);
    	
    	// Faccio una copia senza copiare il carattere finale '\0'
    	char *s2 = (char*)malloc(len1 * sizeof(char));
    	for (int i = 0; i < len1; i++){
    		s2[i] = s1[i];
    	}
    	printf("\nProva 3. ");
    	for (int i = 0; i < len1; i++){
    		printf("%c", s2[i]);
    	}
    	printf("\nProva 4. ");
    	printf("%s", s2);
    	return 0;
    }
    
    Nelle prima due prove tratto s1 come una stringa normale e mi comporto nella prima prova trattandola come un array di char e nella seconda prova faccio una chiamata alla printf con il label "%s".

    Poi copio la stringa evidenziando quello che mi hai fatto notare. che manca uno spazio finale per il carattere '\0'.
    Ma l'output è identico. Perché?

    Questo è l'output.
    
    Prova 1. casa
    Prova 2. casa
    Prova 3. casa
    Prova 4. casa
    
  • Re: Sottostringhe in C

    Ne approfitto per chiedere, in C le stringhe si definiscono nei seguenti modi:
    char s[5] = {'c','i','a','o','\0'};
     char s[] = "ciao"; 
    Posso scrivere anche
    char* s = "ciao";
    Sono scritture equivalenti tutte e 3?
  • Re: Sottostringhe in C

    No, con l'ultima la stringa è costante (non modificabile)
  • Re: Sottostringhe in C

    EdNigma ha scritto:


    Ne approfitto per chiedere, in C le stringhe si definiscono nei seguenti modi:
    char s[5] = {'c','i','a','o','\0'};
     char s[] = "ciao"; 
    Posso scrivere anche
    char* s = "ciao";
    Sono scritture equivalenti tutte e 3?
    char s[] = "ciao";
    o
    char s[5] = {'c','i','a','o','\0'};
    crea un array di 5 char e lo inizializza con gli elementi {'c','i','a','o','\0'}.
    Invece
    char *s = "ciao";
    crea due oggetti:
    - un array statico di sola lettura (costante) e senza nome (identificatore) contenente gli elementi {'c','i','a','o','\0'};
    - un puntatore a char chiamato s che viene inizializzato con l'indirizzo di memoria del primo elemento del suddetto array.

    Da questo presupposto si possono poi fare varie considerazioni, tra cui appunto quella di @oregon.

    Per quanto riguarda la domanda che mi ponevi nel post precedente, domani gli do un'occhiata e ti faccio sapere.
  • Re: Sottostringhe in C

    EdNigma ha scritto:


    Mi riferivo a qualcosa di molto più pratico, strlen() ritorna la lunghezza della stringa senza contare il carattere terminatore, quindi la riga con la malloc() va aggiustata.
    Hai ragione. Posso porti un quesito allora?
    Prendiamo questo codice che ho scritto cosi per prova.
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <stdbool.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
    
    
    int main(int argc, char** argv){
    	char* s1 = "casa\0";
    	unsigned long int len1 = strlen(s1);
    	printf("Prova 1. ");
    	for (int i = 0; i < len1; i++){
    		printf("%c", s1[i]);
    	}
    	printf("\nProva 2. ");
    	printf("%s", s1);
    	
    	// Faccio una copia senza copiare il carattere finale '\0'
    	char *s2 = (char*)malloc(len1 * sizeof(char));
    	for (int i = 0; i < len1; i++){
    		s2[i] = s1[i];
    	}
    	printf("\nProva 3. ");
    	for (int i = 0; i < len1; i++){
    		printf("%c", s2[i]);
    	}
    	printf("\nProva 4. ");
    	printf("%s", s2);
    	return 0;
    }
    
    Nelle prima due prove tratto s1 come una stringa normale e mi comporto nella prima prova trattandola come un array di char e nella seconda prova faccio una chiamata alla printf con il label "%s".

    Poi copio la stringa evidenziando quello che mi hai fatto notare. che manca uno spazio finale per il carattere '\0'.
    Ma l'output è identico. Perché?

    Questo è l'output.
    
    Prova 1. casa
    Prova 2. casa
    Prova 3. casa
    Prova 4. casa
    
    Questo il mio:
    Prova 1. casa
    Prova 2. casa
    Prova 3. casa
    Prova 4. casa-
    Process returned 0 (0x0)   execution time : 0.078 s
    Press any key to continue.
    
    Sei stato più fortunato di me!

    In ogni caso molto più semplicemente:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        char *s1 = "abcdefgh";
        unsigned int l1 = strlen(s1);
        printf("%s\n", s1);
        char *s2 = (char*)malloc(l1 * sizeof(char));
        for(unsigned int i = 0; i < l1; ++i)
        {	
            s2[i] = s1[i];
        }
        printf("%s\n", s2);
        return 0;
    }
    output:
    abcdefgh
    abcdefghÕ¿]M?n
    
    Process returned 0 (0x0)   execution time : 0.117 s
    Press any key to continue.
    
    P.S.
    se vuoi stampare o salvare una stringa contenente delle sottostringhe coincidenti con sequenze di escape, bisogna raddoppiare il carattere \ o % che le iniziano.
    Compila il seguente codice per capire cosa intendo:
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char *s1 = "ab\n??\0!!";
        printf("len1 = %d \ns1 = %s \n\n", strlen(s1), s1);
        char *s2 = "ab\\n??\\0!!";
        printf("len2 = %d \ns2 = %s \n\n", strlen(s2), s2);
        printf("stampo il simbolo della percentuale seguito da una d:  %d \n\n");
        printf("stampo il simbolo della percentuale seguito da una d: %%d \n\n");
        return 0;
    }
    output:
    len1 = 5
    s1 = ab
    ??
    
    len2 = 10
    s2 = ab\n??\0!!
    
    stampo il simbolo della percentuale seguito da una d:  10
    
    stampo il simbolo della percentuale seguito da una d: %d
    
    
    Process returned 0 (0x0)   execution time : 1.301 s
    Press any key to continue.
    
  • Re: Sottostringhe in C

    Questo il mio:
    Prova 1. casa
    Prova 2. casa
    Prova 3. casa
    Prova 4. casa-
    Process returned 0 (0x0) execution time : 0.078 s
    Press any key to continue.

    Sei stato più fortunato di me!
    Sicuramente, comunque ora ho sistemato tutte le funzioni che riguardavano la manipolazione di stringhe con i consigli che ho ricevuto.
    Come logica che c'è dietro i programmi sicuramente ora sono corretti anche formalmente.
    Rimango sempre perplesso di come non abbia mai avuto brutture in rum-time. Anche testando il tuo programma "abcdefgh".
    Sicuramente c'entra l'IDE che uso o il compilatore. Non so.
    se vuoi stampare o salvare una stringa contenente delle sottostringhe coincidenti con sequenze di escape, bisogna raddoppiare il carattere \ o % che le iniziano.
    Ti ringrazio, non ho mai avuto bisogno quindi non mi sono posto il problema ma sicuramente è molto utile.
Devi accedere o registrarti per scrivere nel forum
11 risposte