Oppure

Loading
29/07/17 21:01
L'ultimo campo nel file csv termina con il ; ?

Mostra una linea del csv
09/09/17 14:17
perillitommaso
Allora scusami se ti rispondo dopo tanto tempo ma ho avuto molto da fare con diversi esami, comunque:
sono riuscito a leggere tutti i campi del file csv, leggo tutto il file( unico problema è che leggo 2 volte l'ultimo record ma per il momento non è un problema grave )
Il problema grave adesso è che non mi scrive mezzo rigo sul file ad accesso casuale, la fwrite non funziona anche se tutti i suoi parametri sono corretti. :(
Ti lascio il codice e ti faccio una copia di qualche riga del file csv

struct Admin{
	unsigned int IdUtenti;
	char Nome[20];
	char Cognome[20];
	char Username[20];
	char Password[20];
	char Email[50];
	char Cellulare[10];
};

int main(void) {
	struct Admin f;
	    char line[1024];
	    FILE* ptrUtent;
	    FILE* destinazione;

	    ptrUtent = fopen("Utenti.csv", "r");

	        destinazione = fopen("Utenti.txt","wb+");

	        fscanf(ptrUtent, "%u;%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];", &f.IdUtenti, f.Nome, f.Cognome, f.Username, f.Password, f.Email, f.Cellulare);
	        printf("%u %s %s\n",f.IdUtenti,f.Nome,f.Username);
	        fwrite(&f, sizeof(struct Admin), 1, destinazione);

	        while(fgets(line, 1024, ptrUtent)) {
	        fscanf(ptrUtent, "%u;%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];", &f.IdUtenti, f.Nome, f.Cognome, f.Username, f.Password, f.Email, f.Cellulare);
	        printf("%u %s %s\n",f.IdUtenti,f.Nome,f.Username);
	        fwrite(&f, sizeof(struct Admin), 1, destinazione);

	        }


	    fclose(ptrUtent);
	    fclose(destinazione);


	return 0;
}



file csv:
1;Tommaso;Perilli;password1;perilli;email1@yahoo.it;3333333333;
2;Alessandro;Piscopo;password2;piscopo;email2@gmail.com;4444444444;

EDIT DEL MODERATORE: rimosse mail e numeri di cellulare (per sicurezza anche le password), fa attenzione a pubblicare dati pubblicamente specie se non sono tuoi.
Ultima modifica effettuata da lumo 09/09/17 15:04
aaa
09/09/17 15:16
lumo
Fa attenzione, ho modificato il tuo post.

Comunque il codice funziona, scrivi i dati in formato binario.
Per leggere i dati dal file Utenti.txt dovrai avere un altro programma che fa:

struct Admin f;
fread(&f, sizeof(f), 1, fp);

E a quel punto f sarà popolata con i valori. Ovviamente se apri Utenti.txt con l'editor normale vedrai scritte strane, perché ad esempio il numero IdUtenti verrà salvato così com'è ma l'editor lo interpreterà come carattere.
Inoltre se uno dei tuoi campi, ad esempio Nome[20], venisse riempito solo parzialmente ("TommasoFa attenzione, ho modificato il tuo post.

Comunque il codice funziona, scrivi i dati in formato binario.
Per leggere i dati dal file Utenti.txt dovrai avere un altro programma che fa:

struct Admin f;
fread(&f, sizeof(f), 1, fp);

E a quel punto f sarà popolata con i valori. Ovviamente se apri Utenti.txt con l'editor normale vedrai scritte strane, perché ad esempio il numero IdUtenti verrà salvato così com'è ma l'editor lo interpreterà come carattere.
Inoltre se uno dei tuoi campi, ad esempio Nome[20], venisse riempito solo parzialmente ("Tommaso{parsed_message}", 7 caratteri più terminatore), fwrite scriverà comunque la parte rimanente di caratteri non usati (e deve farlo), ma questi sono memoria non inizializzata e potrebbero avere qualsiasi valore.
Ad esempio quello che viene fuori a me è questo:
cat Utenti.txt
TommasoX!�2Perilli�?ý2Kv��password1�?ý2perilli��'���'email1@yahoo.itX���2P���2��'���=3333333333AlessandroX!�2Piscopo�?ý2Kv��password2�?ý2piscopo��'���'email2@gmail.comX���2P���2��'���=4444444444AlessandroX!�2Piscopo�?ý2Kv��password2�?ý2piscopo��'���'email2@gmail.comX���2P���2��'���=4444444444%   


Se vuoi stampare sul file i valori in formato testuale devi usare fprintf, ma non vedo che senso avrebbe visto che parti già da un file di testo leggibile.

Ti do dei consigli sul codice:
1) impara a indentare bene, tutti i blocchi di codice devono essere allo stesso livello di spaziatura e quando apri un nuovo blocco ({.. }) devi aumentare la spaziatura di un numero fisso di caratteri.
2)fscanf e scanf leggono le stringhe secondo il formato C, cioè vengono memorizzati prima i caratteri e infine il carattere '{parsed_message}' (codifica ascii 0) che indica la fine della stringa.
Quindi per il numero di telefono di 10 caratteri ti serve char Cellulare[11];
In generale tieni presente che il tuo programma non funzionerà bene se viene dati un nome di più di 20 caratteri, perché andrà a sovrascrivere i caratteri di Cognome.
Se vuoi saperne di più suoi problemi di sicurezza che si hanno quando si usa fread così, leggi su internet cos'è un buffer overflow.
Comunque visto che è un codice didattico va bene, l'importante è che tu lo sappia se mai un giorno lavorassi.
3) in fopen non ti serve l'opzione "+" penso.", 7 caratteri più terminatore), fwrite scriverà comunque la parte rimanente di caratteri non usati (e deve farlo), ma questi sono memoria non inizializzata e potrebbero avere qualsiasi valore.
Ad esempio quello che viene fuori a me è questo:
cat Utenti.txt
TommasoX!�2Perilli�?ý2Kv��password1�?ý2perilli��'���'email1@yahoo.itX���2P���2��'���=3333333333AlessandroX!�2Piscopo�?ý2Kv��password2�?ý2piscopo��'���'email2@gmail.comX���2P���2��'���=4444444444AlessandroX!�2Piscopo�?ý2Kv��password2�?ý2piscopo��'���'email2@gmail.comX���2P���2��'���=4444444444%   


Se vuoi stampare sul file i valori in formato testuale devi usare fprintf, ma non vedo che senso avrebbe visto che parti già da un file di testo leggibile.

Ti do dei consigli sul codice:
1) impara a indentare bene, tutti i blocchi di codice devono essere allo stesso livello di spaziatura e quando apri un nuovo blocco ({.. }) devi aumentare la spaziatura di un numero fisso di caratteri.
2)fscanf e scanf leggono le stringhe secondo il formato C, cioè vengono memorizzati prima i caratteri e infine il carattere 'Fa attenzione, ho modificato il tuo post.

Comunque il codice funziona, scrivi i dati in formato binario.
Per leggere i dati dal file Utenti.txt dovrai avere un altro programma che fa:

struct Admin f;
fread(&f, sizeof(f), 1, fp);

E a quel punto f sarà popolata con i valori. Ovviamente se apri Utenti.txt con l'editor normale vedrai scritte strane, perché ad esempio il numero IdUtenti verrà salvato così com'è ma l'editor lo interpreterà come carattere.
Inoltre se uno dei tuoi campi, ad esempio Nome[20], venisse riempito solo parzialmente ("Tommaso{parsed_message}", 7 caratteri più terminatore), fwrite scriverà comunque la parte rimanente di caratteri non usati (e deve farlo), ma questi sono memoria non inizializzata e potrebbero avere qualsiasi valore.
Ad esempio quello che viene fuori a me è questo:
cat Utenti.txt
TommasoX!�2Perilli�?ý2Kv��password1�?ý2perilli��'���'email1@yahoo.itX���2P���2��'���=3333333333AlessandroX!�2Piscopo�?ý2Kv��password2�?ý2piscopo��'���'email2@gmail.comX���2P���2��'���=4444444444AlessandroX!�2Piscopo�?ý2Kv��password2�?ý2piscopo��'���'email2@gmail.comX���2P���2��'���=4444444444%   


Se vuoi stampare sul file i valori in formato testuale devi usare fprintf, ma non vedo che senso avrebbe visto che parti già da un file di testo leggibile.

Ti do dei consigli sul codice:
1) impara a indentare bene, tutti i blocchi di codice devono essere allo stesso livello di spaziatura e quando apri un nuovo blocco ({.. }) devi aumentare la spaziatura di un numero fisso di caratteri.
2)fscanf e scanf leggono le stringhe secondo il formato C, cioè vengono memorizzati prima i caratteri e infine il carattere '{parsed_message}' (codifica ascii 0) che indica la fine della stringa.
Quindi per il numero di telefono di 10 caratteri ti serve char Cellulare[11];
In generale tieni presente che il tuo programma non funzionerà bene se viene dati un nome di più di 20 caratteri, perché andrà a sovrascrivere i caratteri di Cognome.
Se vuoi saperne di più suoi problemi di sicurezza che si hanno quando si usa fread così, leggi su internet cos'è un buffer overflow.
Comunque visto che è un codice didattico va bene, l'importante è che tu lo sappia se mai un giorno lavorassi.
3) in fopen non ti serve l'opzione "+" penso.' (codifica ascii 0) che indica la fine della stringa.
Quindi per il numero di telefono di 10 caratteri ti serve char Cellulare[11];
In generale tieni presente che il tuo programma non funzionerà bene se viene dati un nome di più di 20 caratteri, perché andrà a sovrascrivere i caratteri di Cognome.
Se vuoi saperne di più suoi problemi di sicurezza che si hanno quando si usa fread così, leggi su internet cos'è un buffer overflow.
Comunque visto che è un codice didattico va bene, l'importante è che tu lo sappia se mai un giorno lavorassi.
3) in fopen non ti serve l'opzione "+" penso.
Ultima modifica effettuata da lumo 09/09/17 15:18
aaa
09/09/17 15:23
perillitommaso
Grazie per la risposta, le password sono inventate quindi no problem ahah
comunque, a me risulta che il file sia vuoto, ha 0KB di memoria.. com'è possibile?
Come risolvo d'altronde il doppione dell'ultimo record?
aaa
09/09/17 15:28
perillitommaso
Adesso mi funziona, ho fatto un Clean Project su Eclipse e mi funziona, che cosa strana :-|:-|:-| l'unico problema è l'ultimo record che viene stampato 2 volte :-?
aaa
09/09/17 16:53
perillitommaso
Ho risolto, bastava mettere un controllo sulla fscanf dato che restituisce un valore diverso da EOF quando avviene la lettura.
Grazie comunque :)
aaa
09/09/17 17:31
Mikelius
Semplicemente, evita di leggere un rigo fuori dal while (se il file è vuoto ti accorgi che è bene non farlo),
leggi rigo x rigo finchè non trovi l'EOF con la fgets come hai fatto
e dentro il while utilizza sscanf con la variabile line (perchè la crei, se non la utilizzi??)

se non vuoi caratteri strani potresti azzerarti la struct ad inizio while, in questo modo nel .txt avresti un output tipo
(NUL)(NUL)(NUL)TOMMASO(NUL)(NUL)(NUL)(NUL)PERILLI(NUL)(NUL)(NUL) ecc..
(con notepad++ ad esempio)de gustibus.
Ultima modifica effettuata da Mikelius 09/09/17 17:34
aaa