[ANSI C]problema con strtok

di Anonimizzato8203 il
27 risposte
Ciao a tutti
ho un problema con la funzione strtok in questo programma

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
#include<ctype.h>
#include<time.h>

int main() {    
    int i,j,nq=7;
    char *qspec[7],*p;
    char s2[]="#";
    qspec[0]= "M#Come si chiama il satellite della Terra?#4#B#Giove#Luna#Marte#Terra";
    qspec[1]= "W#Una provincia dell''Umbria#3#2#Terni#Perugia";
    qspec[2]= "N#Un numero primo tra 30 e 40#2#2#31#37";
    qspec[3]= "W#Un anagramma di torta#5#3#trota#rotta#ratto";
    qspec[4]= "N#In che anno nacque Dante Alighieri?#7#1#1256";
    qspec[5]= "M#Chi ha scritto l''Orlando Furioso?#5#C#Torquato Tasso#Dante Alighieri#Ludovico Ariosto#Giovanni Boccaccio";
    qspec[6]= "N#Un cubo di 4 cifre#4#13#1000#1331#1728#2197#17576#2474#3375#4096#4913#5832#6859#8000#9261#";
    for(i=0;i<nq;i++)
        printf("%s\n",qspec[i]);
    for(i=0;i<nq;i++){
        printf("%s ",strtok(qspec[i],s2));
        while((p=strtok(NULL,s2))!=NULL)
            printf("%s ",p);
        printf("\n");
    }
    return 0;
}
questa è una parte del programma, anche se è quella basilare.
In poche parole con le varie parti di ogni stringa di qspec (delimitate da #) devo creare una struct.
Il mio problema era come dividere le stringhe. Andando a spulciare le varie funzioni presenti in string.h ho trovato questa strtok che fa precisamente quello che mi serve.
Però quando eseguo questo programma, si chiude subito e se faccio il debug mi da errore di SEGFAULT. Secondo me dipende dal fatto che non accetta come primo argomento qspec. Ho provato in un altro programma con una sola stringa definita nel main e strtok funzionava perfettamente. Altrimenti qualcuno conosce un altro modo per prendere parti di una stringa con un delimitatore(stavo pensando di usare strchr facendogli scorrere la stringa)?
grazie

27 Risposte

  • Chissà perche questo funziona.
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<string.h>
    #include<ctype.h>
    #include<time.h>
    
    int main() {   
        int i,nq=7;
        char qspec[7][256],*p;
        char s2[]="#";
    	
        strcpy(qspec[0],"M#Come si chiama il satellite della Terra?#4#B#Giove#Luna#Marte#Terra");
        strcpy(qspec[1],"W#Una provincia dell''Umbria#3#2#Terni#Perugia");
        strcpy(qspec[2],"N#Un numero primo tra 30 e 40#2#2#31#37");
        strcpy(qspec[3],"W#Un anagramma di torta#5#3#trota#rotta#ratto");
        strcpy(qspec[4],"N#In che anno nacque Dante Alighieri?#7#1#1256");
        strcpy(qspec[5],"M#Chi ha scritto l''Orlando Furioso?#5#C#Torquato Tasso#Dante Alighieri#Ludovico Ariosto#Giovanni Boccaccio");
        strcpy(qspec[6],"N#Un cubo di 4 cifre#4#13#1000#1331#1728#2197#17576#2474#3375#4096#4913#5832#6859#8000#9261#");
        for(i=0;i<nq;i++)
            printf("%s\n",qspec[i]);
    
        for(i=0;i<nq;i++)
    	{
    		p = strtok(qspec[i],s2);
            
            while(p != NULL)
    		{
                printf("%s ",p);
    			p=strtok(NULL,s2);
    		}
            printf("\n");
        }
        return 0;
    }
    
  • Per favore me lo potresti spiegare:
    -se è dovuto alla strcpy allora non ho proprio capito le stringhe. Se uso strcpy o dichiaro
    
    char *s[];
    s="adaiohf";
    non è la stessa cosa?

    -se è dovuto al fatto che hai specificato la lunghezza massima delle stringhe in qspec, allora devo trovare un altro modo perchè devo scrivere una funzione che ha come parametri (char *qspec[], int nq)

    -se è sbagliato il codice riguardo alla strtok allora prendo il libro di programmazione che ho e lo butto perchè il codice l'ho preso da lì
  • Non ho detto che è sbagliato ma come l'hai definito tu l'inizializzazione per il compilatore hai solo un vettore di 7 puntatori. Quindi credo che è da rivedere quella parte.
  • Purtroppo posso avere solo un array di puntatori. Niente di più.
    Però scusa quello che non capisco è perchè non funziona la strtok. In input deve prendere due puntatori a stringhe, perchè però qspec non gli va bene?
  • Strtok non funziona con il primo parametro costante in quanto viene modificato.
    Leggi qui:http://www.cplusplus.com/reference/clibrary/cstring/strtok/

    Un'alternativa consiste nell'utilizzare strchr.
    
    --- cut ---
        for(i=0;i<nq;i++)
        {
            p=qspec[i];
            while((p=strchr(p,s2))!=NULL)
                printf("%s\n ",p++);
            printf ("\n");
        }
    --- cut ---
    
    EDIT:
    Warning s2 deve essere int.
    
    char * strchr (       char * str, int character );
    
    ~Max
  • Grande Max, ci sono arrivato dopo guardando il codice di strok. Si vede che uso molto il C. L'ultima volta era il 1998.
  • Thx ... ma è deprecata?
  • Che io sappia no. usando la classe std::string pian pianino dimentichi il vecchio C tutto quà.
  • ixamit ha scritto:


    strtok non funziona con il primo parametro costante in quanto viene modificato.
    non ho ben capito perchè le stinghe di qspec sarebbero costanti, però il succo è che non posso usare strtok.

    mi potreste illuminare su una cosa
    se io dichiaro
    
    char *vettore[4];
    ho dichiarato un vettore formato da 4 puntatori, ognuno dei quali punta a una stringa giusto?
  • Hai dichiarato un vettore di 4 puntatori a char che puntano a nulla.
  • Come pensavo.
    se la dichiarazione di vettore[4] è presente in una struct, io devo solo allocare lo spazio per ogni puntatore di vettore giusto?
  • Certo. lo spazio lo devi dichiarare a seconda della lunghezza della stringa che questo puntatore deve puntare. Poi copi la stringa nello spazio puntato dal v con strcpy.
  • Ok. forse sto cominciando a capire i puntatori

    ora una domanda non proprio pertinente con la strtok:
    il programma chesto facendo deve creare, attraverso una funzione, un puntatore a un array di struct.
    alla funzione io passo la dimensione di tale array e poi alloco dinamicamente lo spazio per tale array così
    
    Quiz *q    /*Quiz è il nome della struct*/
    q = (Quiz *)malloc(n*sizeof(Quiz)
    l'elemento q è una struct giusto?
  • Q è un vettore di struct, quindi q è una struct.Giusto.
    Tu invece dici che devi creare un puntatore ad un array di struct. Io il puntatore di un array lo concepisco così:
    
    Quiz *q = (Quiz*)malloc(n*sizeof(Quiz)); //q è un array di struct Quiz
    Quiz **p = &q; //p è un puntatore ad un array di struct.
    
Devi accedere o registrarti per scrivere nel forum
27 risposte