Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Trasformazione da file csv a file binario
Forum - C/C++ - Trasformazione da file csv a file binario - Pagina 2

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
perillitommaso (Normal User)
Pro


Messaggi: 186
Iscritto: 28/01/2014

Segnala al moderatore
Postato alle 16:17
Sabato, 09/09/2017
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
Codice sorgente - presumibilmente C++

  1. struct Admin{
  2.         unsigned int IdUtenti;
  3.         char Nome[20];
  4.         char Cognome[20];
  5.         char Username[20];
  6.         char Password[20];
  7.         char Email[50];
  8.         char Cellulare[10];
  9. };
  10.  
  11. int main(void) {
  12.         struct Admin f;
  13.             char line[1024];
  14.             FILE* ptrUtent;
  15.             FILE* destinazione;
  16.  
  17.             ptrUtent = fopen("Utenti.csv", "r");
  18.  
  19.                 destinazione = fopen("Utenti.txt","wb+");
  20.  
  21.                 fscanf(ptrUtent, "%u;%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];", &f.IdUtenti, f.Nome, f.Cognome, f.Username, f.Password, f.Email, f.Cellulare);
  22.                 printf("%u %s %s\n",f.IdUtenti,f.Nome,f.Username);
  23.                 fwrite(&f, sizeof(struct Admin), 1, destinazione);
  24.  
  25.                 while(fgets(line, 1024, ptrUtent)) {
  26.                 fscanf(ptrUtent, "%u;%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];", &f.IdUtenti, f.Nome, f.Cognome, f.Username, f.Password, f.Email, f.Cellulare);
  27.                 printf("%u %s %s\n",f.IdUtenti,f.Nome,f.Username);
  28.                 fwrite(&f, sizeof(struct Admin), 1, destinazione);
  29.  
  30.                 }
  31.  
  32.  
  33.             fclose(ptrUtent);
  34.             fclose(destinazione);
  35.  
  36.  
  37.         return 0;
  38. }



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 il 09/09/2017 alle 17:04
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 17:16
Sabato, 09/09/2017
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:

Codice sorgente - presumibilmente C/C++

  1. struct Admin f;
  2. 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\0", 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:
Codice sorgente - presumibilmente Plain Text

  1. cat Utenti.txt
  2. 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 '\0' (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 il 09/09/2017 alle 17:18
PM Quote
Avatar
perillitommaso (Normal User)
Pro


Messaggi: 186
Iscritto: 28/01/2014

Segnala al moderatore
Postato alle 17:23
Sabato, 09/09/2017
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?

PM Quote
Avatar
perillitommaso (Normal User)
Pro


Messaggi: 186
Iscritto: 28/01/2014

Segnala al moderatore
Postato alle 17:28
Sabato, 09/09/2017
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 :-?

PM Quote
Avatar
perillitommaso (Normal User)
Pro


Messaggi: 186
Iscritto: 28/01/2014

Segnala al moderatore
Postato alle 18:53
Sabato, 09/09/2017
Ho risolto, bastava mettere un controllo sulla fscanf dato che restituisce un valore diverso da EOF quando avviene la lettura.
Grazie comunque :)

PM Quote
Avatar
Mikelius (Member)
Expert


Messaggi: 525
Iscritto: 14/04/2017

Segnala al moderatore
Postato alle 19:31
Sabato, 09/09/2017
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 il 09/09/2017 alle 19:34
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo