Memorizzare input in formatto csv

di Anonimizzato27295 il
11 risposte
Buongiorno,
devo leggere da stdin una stringa formatta in questo modo:
<intero>;<titolo>;<regista>
Esempio:
1231;via col vento;Victor Fleming
Inizialmente, pensavo di usare una scanf struttura in questo modo:
scanf("%d%*c%100s%*c%50s", numero, titolo, regista);
però il costrutto "%s" si ferma ogni volta che incontra uno spazio.

11 Risposte

  • 1) non e' proprio CSV (COMMA separated value - COMMA=VIRGOLA), ma va bene lo stesso
    2) ci sono librerie apposite per leggere i file CSV, ma si puo' fare a mano
    3) leggi una riga alla volta e la suddividi sui ";"
    4) leggi l'INTERO file come se fosse un'unica striga, QUINDI siddividi la stringa in righe sugli A CAPO e suddividi le righe sui ";"
  • Posta un pezzo significativo di codice.
  • #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define DIM_TITOLO 100
    #define DIM_regista 50
    
    void readInput(int *num, char *titolo, char *regista);
    
    int main()
    {
    	int numero;
    	char titolo[DIM_TITOLO];
    	char regista[DIM_regista];
    	readInput(&numero, titolo, regista);
    	printf("Numero:%d\n", numero);
    	printf("Titolo:%s\n", titolo);
    	printf("regista:%s", regista);
    	
    }
    
    void readInput(int *num, char *titolo, char *regista)
    {
    	while(scanf("%d%*c", num) != 1 || *num < 0)
    	{
    		puts("ERRORE");
    		scanf("%*[^\n]");
    		scanf("%*c");
    	}
    	char temp[DIM_TITOLO+DIM_regista];
    	fgets(temp, DIM_TITOLO+DIM_regista, stdin);
    
    	strcpy(regista, strchr(temp, ';')+1);
    	autore[strlen(autore)-1] = '\0';
    	strncpy(titolo, temp,  strlen(temp) - strlen(regista) - 2);
    }
    Questo è il codice, però nella stringa "Titolo" vi finiscono anche caratteri casuali.
  • Questo è il codice, però nella stringa "Titolo" vi finiscono anche caratteri casuali.
    Ho risolto inizializzando la stringa.
  • Ora ho un altro problema: quando chiamo la funzione "Input" più di una volta, il contenuto della stringa "titolo" non viene inizializzato, ma continua a contenere i dati della lettura precedente.
    Esempio di output
    1231;via col vento;Victor Fleming
    Titolo:via col vento
    2323;Il Signore degli Anelli - La Compagnia dell'Anello;Peter Jackson
    Titolo:Il Signore degli Anelli - La Compagnia dell'Anello
    1231;via col vento;Victor Fleming
    Titolo:via col ventogli Anelli - La Compagnia dell'Anello
    
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define DIM_TITOLO 100
    #define DIM_regista 100
    
    void input(int *numero, char *titolo, char *regista);
    
    int main()
    {
    	unsigned int num;
    	char titolo[DIM_TITOLO] = "";
    	char regista[DIM_regista] = "";
    
    	input(&num, titolo, regista);
    	while(num != 0)
    	{
    		printf("Titolo:%s\n", titolo);
    		input(&num, titolo, regista);
    	}
    }
    
    
    void input(int *numero, char *titolo, char *regista)
    {
    	while(scanf("%d%*c", numero) != 1 || *numero < 0)
    	{
    		puts("ERRORE");
    		scanf("%*[^\n]");
    		scanf("%*c");
    	}
    	if(*numero != 0)
    	{
    		char temp[DIM_TITOLO+DIM_regista] = "";
    		strcpy(titolo, "");
    		strcpy(regista, "");
    
    		fgets(temp, DIM_TITOLO+DIM_regista, stdin);
    		strcpy(regista, strchr(temp, ';')+1);
    		regista[strlen(regista)-1] = '\0';
    		strncpy(titolo, temp,  strlen(temp) - strlen(regista) - 2);
    	}
    }
    
  • Ma qual è l'input ?
  • oregon ha scritto:


    Ma qual è l'input ?
    Le scritte in grassetto sono l'input
    1231;via col vento;Victor Fleming
    Titolo:via col vento
    2323;Il Signore degli Anelli - La Compagnia dell'Anello;Peter Jackson
    Titolo:Il Signore degli Anelli - La Compagnia dell'Anello
    1231;via col vento;Victor Fleming
    Titolo:via col ventogli Anelli - La Compagnia dell'Anello
  • Potresti usare un banalissimo ciclo for per mettere tutti i byte di titolo a zero prima di caricare il nuovo titolo...
  • Weierstrass ha scritto:


    Potresti usare un banalissimo ciclo for per mettere tutti i byte di titolo a zero prima di caricare il nuovo titolo...
    Con le istruzioni
    
    char temp[DIM_TITOLO+DIM_regista] = "";
    strcpy(titolo, "");
    strcpy(regista, "");
    
    le tre stringhe vengono effettivamente inizializzate, ma - in qualche modo - con l'istruzione
    strncpy(titolo, temp,  strlen(temp) - strlen(regista) - 2);
    nella stringa "titolo" (che è vuota) ci va a finire il contenuto della vecchia stringa "titolo" ed il contenuto della stringa "temp".
    ESEMPIO DI OUTPUT:

    2323;Il Signore degli Anelli - La Compagnia dell'Anello;Peter Jackson
    Contenuto stringa titolo prima di strncpy:
    Contenuto stringa temp prima di strncpy: Il Signore degli Anelli - La Compagnia dell'Anello;Peter Jackson
    Titolo:Il Signore degli Anelli - La Compagnia dell'Anello

    1231;via col vento;Victor Fleming
    Contenuto stringa titolo prima di strncpy:
    Contenuto stringa temp prima di strncpy: via col vento;Victor Fleming
    Titolo:via col ventogli Anelli - La Compagnia dell'Anello
    (L'input è in grassetto, mentre le parole sottolineate sono il contenuto della string temp e titolo, prima dell'istruzione:
    strncpy(titolo, temp,  strlen(temp) - strlen(regista) - 2);
    )
  • Si ma non devi spiegarmi quello che succede, ti ho detto una delle possibili banali soluzioni che potresti implementare invece di strcpy con "" che mette a zero solo il primo byte.
  • Weierstrass ha scritto:


    Si ma non devi spiegarmi quello che succede, ti ho detto una delle possibili banali soluzioni che potresti implementare invece di strcpy con "" che mette a zero solo il primo byte.
    Funziona! Grazio per l'aiuto.
    Ripropongo il codice aggiornato:
    
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define DIM_TITOLO 100
    #define DIM_regista 100
    
    void input(int *numero, char *titolo, char *regista);
    
    int main()
    {
    	unsigned int num;
    	char titolo[DIM_TITOLO] = "";
    	char regista[DIM_regista] = "";
    
    	input(&num, titolo, regista);
    	while(num != 0)
    	{
    		printf("Titolo:%s\n", titolo);
    		input(&num, titolo, regista);
    	}
    }
    
    
    void input(int *numero, char *titolo, char *regista)
    {
    	while(scanf("%d%*c", numero) != 1 || *numero < 0)
    	{
    		puts("ERRORE");
    		scanf("%*[^\n]");
    		scanf("%*c");
    	}
    	if(*numero != 0)
    	{
    		char temp[DIM_TITOLO+DIM_regista] = "";
    		unsigned short i = 0;
    
    		while(titolo[i] != '\0' && i < DIM_TITOLO)
    		{
    			titolo[i] = '\0';
    			i++;
    		}
    		i = 0;
    		while(regista[i] != '\0' && i < DIM_regista)
    		{
    			regista[i] = '\0';
    			i++;
    		}
    
    		fgets(temp, DIM_TITOLO+DIM_regista, stdin);
    		strcpy(regista, strchr(temp, ',')+1);
    		regista[strlen(regista)-1] = '\0';
    		strncpy(titolo, temp,  strlen(temp) - strlen(regista) - 2);
    	}
    }
    
Devi accedere o registrarti per scrivere nel forum
11 risposte