Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 21
  1. #1

    Programma - segmentatio faul

    caio ragazzi sono nuovo del forum e del C..
    devo risolvere questo esercizio,

    Scrivere una funzione int phoneWords(char *words[], int n, char *map[]) che ritorna il numero di numeri di telefono validi che grazie alla mappa cifre-lettere map possono formare combinazioni alfanumeriche presenti nell'array di n stringhe words. Una sequenza di cifre è un numero di telefono valido se ha lunghezza 10 e non inizia per 00 o per 1.

    La mappa map attesa dalla funzione è un array di 10 stringhe tale che:

    * map[i] è il puntatore ad una stringa che contiene le lettere (caratteri alfabetici maiuscoli) associate alla cifra i;
    * ogni carattere alfabetico maiuscolo appare una e una sola volta in map e nessun'altro carattere appare in map.

    In caso gli argomenti di input non soddisfino le precondizioni necessarie alla corretta esecuzione della funzione, questa deve restituire -1.

    Le stringhe in words possono contenere anche caratteri non alfanumerici, in questo caso vanno ignorati. Ogni carattere alfabetico (maiuscolo o minuscolo) va fatto corripondere ad una cifra secondo la mappa map e ogni carattere numerico va fatto corrispondere alla cifra corrispondente.


    il programma che ho scritto, sicuramente con un codice abbastanza penoso, non da ne warning ne errori e compila bene, ma quando lo eseguo mi da segmentation fault.

    codice:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    int phonewords(char *words[], int n, char *map[]);
    int numCtrl(char *words[], char *map[], int f, char *telefono[], int n);
    int carNum(char carattere, char *map[]);
    
    int main()
    {
    int n;
    n = 13;
    
    char *words[n];
    words[0] = "lleaseCall";
    words[1] = "hello-hello";
    words[2] = "ciaociao";
    words[3] = "FIRMAMENTO";
    words[4] = "TELEFONAMI";
    words[5] = "CHIAMA1ORA";
    words[6] = "TELEDOMANI";
    words[7] = "telefona domani";
    words[8] = "ChiamaOra";
    words[9] = "0 OK 1 CALL 99";
    words[10] = "PLEASE ball";
    words[11] = "1Chiamaora";
    words[12] = "00OKOKOKOK";
    
    
    char *map[10];
    map[0] = "";
    map[1] = "";
    map[2] = "ABC";
    map[3] = "DEF";
    map[4] = "GHI";
    map[5] = "JKL";
    map[6] = "MNO";
    map[7] = "PQRS";
    map[8] = "TUV";
    map[9] = "WXYZ";
    printf("ci sono %d numeri di tel\n", phonewords(words, 13,map)); 
    
    return 0;
    }
    
    
    int phonewords(char *words[], int n, char *map[])
    {
    char *telefono[n];
    int parole;
    int risultato;
    risultato = 0;
    int c = 0;
    int f = 0;
    int aux = 0;
    int aux2 = 0;
    // devo fare una funzione che verifichi la correttezza della map[] che mi viene passata
    
    
    
    
    // controllo che le parole siano di 10 caratteri e che siano alfanumerici
    for (parole = 0; parole < n; parole++)
    {printf("Parole = %d\n", parole);
    	if (strlen(words[f]) >= 10)
    	{
    		aux = strlen(words[f]);printf("aux = %d\n", aux);
    		for (c = 0; c < aux; c++)
    		{
    			if (isalnum(words[f][c]) != 0) aux2++; printf("aux2 = %d\n", aux2);
    		}
    
    		if (aux2 == 10)
    		{
    			if (numCtrl(words, map, f, telefono, n) == 1)
    			{
    				risultato++; printf("Risultato = %d\n", risultato);
    			}
    		}
    	}
    aux = 0;
    aux2 = 0;
    f++;printf("f = %d\n", f);
    }
    
    return risultato;
    }// chiude phonewords
    
    
    // da qui in poi il codice serve a verificare che le parole passate DI 10 CARATTERI soddisfino la condizione 00 e 1
    
    // definizione delle funzioni usate
    int numCtrl(char *words[], char *map[], int f, char *telefono[], int n)  
    {
    char stato;
    stato = 'i';
    char car;
    int e;
    int risultato;
    int b;
    b = 0;
    
    int help;
    for (e = 0; e < 10; e++)
    {
    	car = words[f][e]; printf("valore di car %c\n", car);
    	switch (stato)
    	{
    		case 'i':	if (car == '1')
    				{
    					risultato = 0;
    					e = 10;
    				}
    				else if (car == '0')
    				{
    					stato = 'z';
    				}
    				else if (isalnum(car) == 0)
    				{
    					stato = 'i';
    				}
    				else
    				{	printf("sto passando il carattere ottenuto alla funzione carNum\n");
    					risultato = 1;
    					/*telefono[n][b]*/ help = carNum(car, map); printf("help %d \n", help);  /* QUA SI VERIFICA L'ERRORE! NON VIENE STAMPATO IL PRINTF, ho temporaneamente messo la variabile int help perchè un altro prob da risolvere è convertire l'int che ricevo dalla funzione in un char da scrivere in telefono[n][b]*/
    					b++;
    					stato = 'n';
    				}
    		break;
    
    		case 'z':	if (car == '0')
    				{
    					risultato = 0;
    					e = 10;
    				}
    				else if (isalnum(car) == 0)
    				{
    					stato = 'z';
    				}
    				else
    				{
    					risultato = 1;
    					telefono[n][b] = '0';
    					b++;
    					telefono[n][b] = carNum(car, map);
    					b++;
    					stato = 'n';
    				}
    		break;
    		
    		case 'n':	
    				telefono[n][b] = (char)carNum(car, map);
    				b++;
    		break;
    	}
    }
    
    return risultato;
    }
    
    
    int carNum(char carattere, char *map[])
    {
    int conta;
    conta = 0;
    
    	carattere = (char)toupper(carattere);
    	printf("Ho reso maiuscolo il carattere %c\n", carattere);
    	do
    	{printf("map in 0 = %c\n", map[conta][0]);
    		if(strchr(map[conta], carattere) == NULL) conta++;
    	} while (strchr(map[conta], carattere) == NULL);
    
    printf("conta = %d\n", conta);
    return conta;
    }
    l'errore si verifica appena terminata la funzione carNum richiamata nell'ultimo else del case 'i' dello switch...
    Se qualcuno ha una vaga idea di cosa ci sia di sbagliato sarei molto felice di saperlo..
    Grazie a tutti!

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320

    Moderazione

    Come indicato espressamente nel Regolamento interno (da leggere), il linguaggio va obbligatoriamente indicato nel titolo ed il codice va obbligatoriamente postato indentato e all'interno degli appositi tag CODE.

    Correggo io questa discussione.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    ok grazie mille..
    Grazie a tutti!

  4. #4
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Il mio debugger segnala l' errore esattamente in questa riga:
    codice:
    telefono[n][b] = (char)carNum(car, map);
    Adesso non ho avuto molto tempo per leggere l' intero codice,ma sei sicuro che i valori di n e b non vadano oltre la dimensione allocata per questa matrice?
    Il segmentation fault avviene quando tenti di scrivere sopra una porzione di memoria non allocata,prima di questa istruzione avevi assegnato:
    codice:
    b++;
    Non stai andando oltre i limiti dell' array?

  5. #5
    grazie mille.. ora controllo ma se non ricordo male, ora sono con l'iPod e non ho il codce visibile sott'occhio, ma mi sa che è n il problema..
    Grazie a tutti!

  6. #6
    codice:
    char *words[n];
    words[0] = "lleaseCall";
    words[1] = "hello-hello";
    words[2] = "ciaociao";
    words[3] = "FIRMAMENTO";
    words[4] = "TELEFONAMI";
    words[5] = "CHIAMA1ORA";
    words[6] = "TELEDOMANI";
    words[7] = "telefona domani";
    words[8] = "ChiamaOra";
    words[9] = "0 OK 1 CALL 99";
    words[10] = "PLEASE ball";
    words[11] = "1Chiamaora";
    words[12] = "00OKOKOKOK";
    
    
    char *map[10];
    map[0] = "";
    map[1] = "";
    map[2] = "ABC";
    map[3] = "DEF";
    map[4] = "GHI";
    map[5] = "JKL";
    map[6] = "MNO";
    map[7] = "PQRS";
    map[8] = "TUV";
    map[9] = "WXYZ";
    Queste assegnazioni sono pericolose, attento.
    Dovresti dichiarare quelle matrici const, perchè tu assegni dei valori const char* a dei puntatori non allocati, e non allocandoli non li puoi usare, perchè se provi a fare una modifica su una di quelle stringhe, andresti in segment fault perchè provi a modificare un'area di memoria const.

    Se vuoi fare modifiche su quelle stringhe, prima devi allocarle, poi con strcpy copi le stringhe costanti in quelle stringhe allocate.

  7. #7
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Eppure io molte volte ho creato funzioni che ritornano stringhe non allocate,c'è qualcosa che non mi quadra
    Se scrivo ad esempio:
    codice:
    char *stringa;
    stringa="ciao";
    Anche se devo dire che l' ho fatto raramente, se non le modifico non ricevo segmentation fault,ne ho abusato molte volte senza saperlo.
    Se non volessi allocarle dovrei dichiararle const e sarei dentro gli standard del c?

  8. #8
    Certo.
    Ogni stringa, numero o qualsiasi cosa che assegni tu, viene allocato in una zona dell'eseguibile, che viene assegnato implicitamente come puntatore.

    Es, scrivendo:
    codice:
    char* stringa = "ciao";
    il compilatore fa una cosa del genere

    codice:
    const char string1[] = "ciao";
    char* stringa = string1;
    la faccenda poi non è così semplice.

    Comunque fatto sta che stringa è una array di char valido, solo che non puoi modificarlo, in quanto è costante, puoi solo leggerlo.
    Se allochi un array e successivamente copi con strcpy la stringa costante, allora il tuo array è modificabile.

    codice:
    char *stringa = (char*)malloc(20*sizeof(char));
    strcpy(stringa, "ciao");

  9. #9
    Originariamente inviato da lolide
    codice:
    char *words[n];
    words[0] = "lleaseCall";
    words[1] = "hello-hello";
    words[2] = "ciaociao";
    words[3] = "FIRMAMENTO";
    words[4] = "TELEFONAMI";
    words[5] = "CHIAMA1ORA";
    words[6] = "TELEDOMANI";
    words[7] = "telefona domani";
    words[8] = "ChiamaOra";
    words[9] = "0 OK 1 CALL 99";
    words[10] = "PLEASE ball";
    words[11] = "1Chiamaora";
    words[12] = "00OKOKOKOK";
    
    
    char *map[10];
    map[0] = "";
    map[1] = "";
    map[2] = "ABC";
    map[3] = "DEF";
    map[4] = "GHI";
    map[5] = "JKL";
    map[6] = "MNO";
    map[7] = "PQRS";
    map[8] = "TUV";
    map[9] = "WXYZ";
    Queste assegnazioni sono pericolose, attento.
    Dovresti dichiarare quelle matrici const, perchè tu assegni dei valori const char* a dei puntatori non allocati, e non allocandoli non li puoi usare, perchè se provi a fare una modifica su una di quelle stringhe, andresti in segment fault perchè provi a modificare un'area di memoria const.

    Se vuoi fare modifiche su quelle stringhe, prima devi allocarle, poi con strcpy copi le stringhe costanti in quelle stringhe allocate.
    Si, mi trovo pienamente d'accordo, a prima vista dovrebbe essere qua l'errore.
    C'è qualcosa che non quadra in queste assegnazioni, perchè vengono fatte a aree di memoria non allocate.
    Prova a risolvere, mettendo prima delle rispettive assegnazioni, ad esempio:

    codice:
    int MAXDIM = 25;
    typedef char string [MAXDIM];
    string words [n];
    string map [10];
    Ovviamente ho dato un valore casuale a MAXDIM, scegline tu uno appropriato al tuo caso.
    Poi, come diceva lolide, dopo più che assegnare le singole stringhe, di sicuro risulta più sicuro usare la strcpy per ognuna, ad esempio:

    codice:
    strcpy (words[0], "lleaseCall");
    Facci sapere se hai risolto
    Salute a voi, da Laikius!

    --> Faber est suae quisque fortunae <--

  10. #10
    il fatto è che tutto il main io l'ho creato solamente per provare le funzioni.
    il mio es richiede la funzione phonewords che poi io ho utilizzato con altre funzioni... il main quindi lo crea il computer che deve provare il mio programma e mi passa (char *words, int n, char *map) mi sembra.. sta scritto nelle prime righe del mio primo post..
    Grazie a tutti!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.