Linguaggio C, dividere una stringa in più stringhe

di il
14 risposte

Linguaggio C, dividere una stringa in più stringhe

Testo:

Definire il tipo di dato record Automobile, contenente i seguenti campi:
- marca, di tipo stringa (max 20 caratteri)
- modello, di tipo stringa (max 20 caratteri)
- prezzo, di tipo intero

Implementare la funzione C: void leggi_automobili(char* nomefile, Automobile parco[10], int *n) che, presi in input una stringa contenente il percorso di un file, un array di Automobile di dimensione 10 ed un puntatore ad intero n, inserisce nell’array, partendo dalla componente 0, tutte le automobili rappresentate nel file, seguendo lo stesso ordine dell’array, ed assegna alla variabile puntata da n il numero di componenti significative dell’array (ovvero quante automobili vi sono state inserite).
Il formato del file è il seguente:
- la prima riga del file contiene il numero di automobili contenute nel file
- ciascuna delle successive righe contiene, nell’ordine specificato, la marca, il modello ed il prezzo dell’automobile.
Assumere che il file non contenga mai più di 10 automobili.


Il file txt è il seguente
5
fiat panda 9000
lancia y 12500
volkswagen golf 15000
fiat punto 11000
audi quattro 60000
struct:
typedef struct{
	
	char marca[20];
	char modello[20];
	int prezzo;
}Automobile;
Funzione
void leggi_automobili(char* nomefile, Automobile parco[10], int *n)
{
	FILE *f = fopen(nomefile, "r");
	int i = 0;
	char buffer[100], *str;
	if(f == NULL) printf("Errore apertura file");
	else
	{
		fscanf(f, "%d", &*n);
		if(*n > 10)
		{
			printf("Il parco non puo' contenere piu' di dieci automobili.");
		}
		else
		{
			while(!feof(f))
			{
				fseek(f, 2, 0);
				str = fgets(buffer, 200, f);
				while(str[i] == ' ') //non so come continuare

					
			}
	
			

		}
	}
	
}
str l'ho stampata e contiene "fiat panda 9000". Devo dividere la stringa in sottostringhe secondo gli spazi, in modo tale che parco.marca = fiat, parco.modello = panda, parco.prezzo = 9000.

Ho visto in giro che ci sono diverse funzioni come strtok, substr etc. Ma non so quale utilizzare. Cosa mi consigliate? Grazie

14 Risposte

  • Re: Linguaggio C, dividere una stringa in più stringhe

    Strtok
  • Re: Linguaggio C, dividere una stringa in più stringhe

    void leggi_automobili(char* nomefile, Automobile parco[10], int *n)
    {
    	FILE *f = fopen(nomefile, "r");
    	int i = 0;
    	char buffer[100], *str, *token;
    	if(f == NULL) printf("Errore apertura file");
    	else
    	{
    		fscanf(f, "%d", &*n);
    		if(*n > 10)
    		{
    			printf("Il parco non puo' contenere piu' di dieci automobili.");
    			return;
    		}
    		else
    		{
    			fseek(f, 2, 0);
    			//while(!feof(f))
    			//{
    				
    				str = fgets(buffer, 200, f);
    				token = strtok(str, " ");
    				while(token != NULL)
    				{
    					//printf("The token is: %s\n", token);
    					strcpy(parco[0].marca, token);
    					token = strtok(NULL, " ");
    					strcpy(parco[0].modello, token);
    					token = strtok(NULL, " ");
    					parco[0].prezzo = token;
    					token = strtok(NULL, " ");
    				}
    				printf("marca: %s", parco[0].marca);
    				printf("modello: %s", parco[0].modello);
    				printf("prezzo: %d", parco[0].prezzo);
    				
    			//}
    			
    
    		}
    	}
    	
    }

    Output:


    marca: fiatmodello: pandaprezzo: -999418661

    Non ho utilizzato la strcpy con parco[0].prezzo perché è un intero. Ho fatto bene? Però me lo stampa male.
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Strtok() ti ritorna un char *, un puntatore alla stringa; per trasformarlo in intero devi utilizzare atoi()
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Ma quindi strtok la devo togliere ed utilizzare solo atoi?
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Strtok la usi per ottenere la sottostringa e la atoi per convertire la sottostringa ottenuta

    P.S. Il ciclo while non ha senso dato che la strtok la usi per ogni campo
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Ok, funziona.
    Però, quando faccio la stessa operazione per caricare l'intero array di struttura parco:
    void leggi_automobili(char* nomefile, Automobile parco[10], int *n)
    {
    	FILE *f = fopen(nomefile, "r");
    	int i = 0;
    	char buffer[100], *str, *token;
    	if(f == NULL) printf("Errore apertura file");
    	else
    	{
    		fscanf(f, "%d", &*n);
    		if(*n > 10)
    		{
    			printf("Il parco non puo' contenere piu' di dieci automobili.");
    			return;
    		}
    		else
    		{
    			fseek(f, 2, 0);
    			while(!feof(f))
    			{
    				while( i < *n)
    				{
    					str = fgets(buffer, 200, f);
    					token = strtok(str, " ");
    					while(token != NULL)
    					{
    						//printf("The token is: %s\n", token);
    						strcpy(parco[i].marca, token);
    						token = strtok(NULL, " ");
    						strcpy(parco[i].modello, token);
    						token = strtok(NULL, " ");
    						parco[i].prezzo = atoi(token);
    						token = strtok(NULL, " ");
    					}
    					i++;
    
    				}
    				
    			}
    			for(i = 0; i < *n; i++)
    			{
    				printf("marca: %s\n", parco[i].marca);
    				printf("modello: %s\n", parco[i].modello);
    				printf("prezzo: %d\n", parco[i].prezzo);
    				printf("\n");
    			}
    				
    		}
    	}
    }
    
    
    Non mi stampa niente. Sto sbagliando sicuro qualcosa con i cicli
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Così non si capisce ... sicuramente la strtok non è usata correttamente ...

    Posta il main e il file dei dati ...
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Sì, scusa.

    Main:
    #include "esercizio.h"
    
    int main(int argc, char** argv){
        char* nomefile = "file1.txt";
        
        Automobile parco[10];
        int n;
        leggi_automobili(nomefile,parco,&n);    
        
    }

    Dati:

        5
        fiat panda 9000
        lancia y 12500
        volkswagen golf 15000
        fiat punto 11000
        audi quattro 60000
    
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Quindi ...

    La fscanf deve essere così
    
          fscanf(f, "%d\n", n);
    
    la fseek la devi eliminare e devi eliminare anche il ciclo con la feof e il while della strtok ... in pratica, dall'else fino alla for diventa
    
          else
          {
    		 while( i < *n)
    		 {
    			str = fgets(buffer, 200, f);
    			token = strtok(str, " ");
    			strcpy(parco[i].marca, token);
    			token = strtok(NULL, " ");
    			strcpy(parco[i].modello, token);
    			token = strtok(NULL, " ");
    			parco[i].prezzo = atoi(token);
    
    			i++;
     		 }
    
                  for(i = 0; i < *n; i++)
    
    Vedi tu il perché dei vari cambiamenti
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Ok, funziona.

    Alla fine la feof era inutile in questo caso perché il while(i < *n) è già sufficiente, infatti esso fa tanti cicli quante sono le macchine da inserire (quindi quante ce ne sono nel file stesso).

    La fseek l'hai tolta perché hai messo lo \n nello scanf.

    Per quanto riguarda con lo fscanf(f, "%d\n", &*n); funziona anche così.

    Quindi fscanf(f, "%d\n", n); è uguale a fscanf(f, "%d\n", &*n); ?

    Grazie
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Il fatto è che gli operatori & e * sono uno l'opposto dell'altro quindi &* non si scrive
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Ok, capito. Grazie ancora
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Testo:
    b) Infine, implementare la funzione C: Automobile* acquistabili(Automobile* parco, int n, int disponibilita, int *m), che,
     presi in input un array “parco” di Automobile le cui prime n componenti sono significative, ed un intero disponibilità,
     restituisce un nuovo array contenente tutte e sole le automobili contenute in parco, il cui prezzo è minore o uguale di disponibilita, 
    ed inserisce nella variabile puntata da m il numero di componenti dell’array resituito.
    

    Testo.txt:


    Main:
    int main(int argc, char** argv){
        char* nomefile = "file1.txt";
        
        Automobile parco[10];
        int n;
        leggi_automobili(nomefile,parco,&n);
        print_parco(parco, n);
        
        int m;
        
        Automobile* acq = acquistabili(parco,n,13000,&m); 
    }
        
    

    Funzioni:

    Automobile* acquistabili(Automobile* parco, int n, int disponibilita, int* m)
    {
    	Automobile *parco_disp;
    	int i;
    	*m = 0; 
    	for(i = 0; i < n; i++)
    		if(parco[i].prezzo < disponibilita)
    			*m = *m + 1;
    			
    	parco_disp = (Automobile *) malloc (*m * sizeof(Automobile));
    	
    	for(i = 0; i < n; i++)
    	{
    		if(parco[i].prezzo <= disponibilita)
    		{
    			strcpy(parco_disp[i].marca, parco[i].marca);
    			strcpy(parco_disp[i].modello, parco[i].modello);
    			parco_disp[i].prezzo = parco[i].prezzo;
    		}
    	}
    	printf("*m: %d", *m);
    	printf("\n");
    	for(i = 0; i < *m; i++)
    	{
    		printf("marca_disp: %s\n", parco_disp[i].marca);
    		printf("modello_disp: %s\n", parco_disp[i].modello);
    		printf("prezzo_disp: %d\n", parco_disp[i].prezzo);
    		printf("\n");
    	}
    
    }
    Mi stampa:

    *m: 5
    marca_disp: fiat
    modello_disp: panda
    prezzo_disp: 9000

    marca_disp: lancia
    modello_disp: y
    prezzo_disp: 12500

    marca_disp:
    modello_disp:
    prezzo_disp: 0

    marca_disp: fiat
    modello_disp: punto
    prezzo_disp: 11000

    marca_disp:
    modello_disp:
    prezzo_disp: 0


    Perché alcuni sono vuoti?
  • Re: Linguaggio C, dividere una stringa in più stringhe

    Mancano due funzioni ...

    Comunque, questa

    if(parco.prezzo < disponibilita)

    deve essere

    if(parco.prezzo <= disponibilita)

    e nel ciclo for, al solito, l'indice i aumenta sempre, anche quando la if non è soddisfatta. Ma NON deve essere così perché deve aumentare SOLO se la if viene eseguita.

    Visto che fai sempre gli stessi errori sui cicli, penso che tu non li abbia compreso veramente ...
Devi accedere o registrarti per scrivere nel forum
14 risposte