|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
[C] Aiutino con fread & fwrite e array dati.
Salve a tutti, dopo un po di ricerche infruttuose sia su google che sul forum mi ritorvo costretto a farvi una domanda su queste due funzioni.
Io devo leggere/salvare il file .dat che ho allegato(rinominato .txt per spedirlo) sfruttando solo le funzioni fread e fwrite. Precedentemente avevo fatto delle funzioni che leggevano/salvavano il file con fscanf/fprintf ma adesso devo utilizzare queste funzioni. Ho fatto le mie belle funzioncine ma ho dei risultati sbagliati. Potreste darmi una manina ![]() Queste sono le funzioni Codice:
int readPESI(double *p_ID, int dimens) { FILE *pFile; double buffer; int punti; pFile = fopen ( "pesi.dat" , "rb" ); if (pFile==NULL) {fputs ("File error",stderr); exit (1);} punti = fread (p_ID,sizeof(double),dimens,pFile); if (punti != dimens) {fputs ("Errore letture",stderr); exit (3);} return punti; } Codice:
int writeOUTPUT(double *buffer, int punti) { FILE *pFile; pFile = fopen("myfile.dat","wb" ); fwrite (buffer ,sizeof(double), punti, pFile); fclose (pFile); return 0; }
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Nessuno mi da un aiutino
![]() Codice:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <float.h> int readFILE(double *p_ID, int dimens) { FILE *pFile; int punti; pFile = fopen ( "pesi.dat" , "rb" ); if (pFile==NULL) {fputs ("File error",stderr); exit (1);} // copy the file into the buffer: punti = fread(p_ID,sizeof(double),dimens,pFile); if (punti != dimens) {fputs ("Reading error",stderr); exit (3);} return punti; } int writeOUTPUT(double *buffer, int punti) { FILE *pFile; pFile = fopen("myfile.dat","wb" ); fwrite (buffer ,sizeof(double), punti, pFile); fclose (pFile); return 0; } int main() { double *p_ID; int punti,i; int dimens; dimens=20; p_ID =(double *)calloc(dimens,sizeof(double)); if (p_ID == NULL) {fputs ("Memory error",stderr); exit (2);} punti=readFILE(p_ID, dimens); for(i=0;i<punti;i++) printf("p_ID[%d]=%g\n",i,p_ID[i]); writeOUTPUT(p_ID, punti); system("PAUSE"); return 1; } ![]() ![]() ![]() Grazie
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quello è un file di testo e non può essere letto con fread. O meglio, volendo puoi leggere il buffer testuale e poi trasformarlo in double, ma non ha senso.
Per leggere con fread il file deve essere binario quindi ci deve essere memorizzata la rappresentazione in memoria di ogni double. |
![]() |
![]() |
![]() |
#4 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
Comunque, premesso che devo, ![]() 1 - leggere i numeri come testo con fread e poi convertirli in numeri 2 - aprire i file *.dat in Octave o Matlab e salvarli come file binari grazie cionci
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Allora leggiti la stringa fino allo spazio, o se le colonne sono predefinite leggi subito la dimensione corretta in un vettore di stringhe e poi ci aggiungi in fondo il carattere di fine stringa.
|
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
Non mi abbandonare ![]()
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#7 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Ciao,
ogni file contiene, sempre, per ogni riga, due numeri separati da spazio? O il formato varia da file a file? Stavo pensando di gestire la cosa con un automa a stati finiti(niente di complicato, lo vedrai quando posterò il codice). ![]() |
![]() |
![]() |
![]() |
#8 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
Aspetto con impazienza il tuo codice. Buonanotte
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
Anzi, facciamo prima, la lunghezza della riga è fissa ? In tal caso conta la dimensione dei caratteri sulla riga, aggiungici un +4 in fondo (+1 per lo spazio, +1 per \r, +1 per \n, +1 per il carattere di fine stringa). Dovrebbe venire fuori 14 * 2 + 4 = 32 Leggi 31 byte con fread mettendoli direttamente nel vettore. Inserisci alla posizione 31 il carattere '\0'. Usa sscanf per convertire i due numeri in double leggendo con lo specificatore "%Le %Le". |
|
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Buongiorno cionci per adesso sto facendo cosi:
funzione Matlab Codice:
[fnome percorso]=uigetfile('*.dat','Scegli il file da convertire'); dati=load([percorso fnome]).'; fid = fopen('pesi.bin', 'wb'); fwrite(fid, dati, 'double'); fclose(fid); Codice:
fid = fopen('pesi.bin', 'rb'); dati = fread(fid, 'double'); fclose(fid); Grazie PS L'utilizzo della funzione atof ha senso? Non vorrei aver capito male come funziona.
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
![]() |
![]() |
![]() |
#11 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
sono stato giustamente richiamato dal moderatore: non si possono postare soluzioni complete. Rimango dell'idea che un automa a stati finiti sia l'ideale per questo tipo di problemi(considerando anche l'efficienza, in termini, dico, di velocità di esecuzione). Se vuoi ti posso spiegare come funziona. Non c'è bisogno di utilizzare particolari funzioni; soltanto loop & switch ![]() ![]() |
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Mi dispiace che il moderatore ti abbia richiamato. Vorrei fare una precisazione, precedentemente avevo risolto la lettura dei file in altro modo adesso mi trovo costretto ad utilizzare fread e di conseguenza ho dovuto cambiare approccio.
A questo punto penso che avrebbe fatto comodo avere una soluzione piu autarchica come la tua piuttosto che fare la gabola di utilizzare un programma per convertire i dati. Mi farebbe piacere sapere la tua soluzione ma non voglio farti avere problemi con il moderatore. Forse l'algoritmo in pseudocodice si puo postare ma vedi cosa ne pensa cionci. Per adesso devo andare avanti con questa strada. Grazie ciao
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 29-11-2008 alle 15:49. |
![]() |
![]() |
![]() |
#13 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
![]() Prova a seguire i suggerimenti di Cionci(il moderatore in questione ![]() ![]() ![]() |
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
|
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Siccome le cose non vogliono mai andarmi lisci mi tocca tornare indietro. Con il mio metodo sembrava andare bene ma su un file più complesso ho dei problemi: la prima riga la riesco ad organizzare bene nella matrice ma a meta della seconda riga compare un numero sballato e da li in poi non corrispondo piu le colonne ed a volte ci sono anche valori sballati.
Ricapitolando cosa mi consigliate di fare? Vincenzo prima di avventurami con gli automi a stati finiti provo la soluzione di Cionci, da quel che ho capito dovrei leggere n byte per volta, giusto? Prima vorrei un consiglio: Codice:
1.4430613e+000 3.6076467e+000_-2.6477394e-005 4.7404982e+001 3.9992000e+000 9.0209209e-001 4.0000000e-001 5.0506966e+000 3.6076293e+000__1.2055733e-006 4.7406928e+001 4.0000000e+000 9.0190732e-001 1.4000000e+000 Grazie, buonanotte.
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 29-11-2008 alle 23:33. |
![]() |
![]() |
![]() |
#16 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Probabilmente la tua soluzione non tiene conto dei caratteri per andare capo. Aprendo il file in binario (con la b nella modalità di apertura). il carattere che manda a capo il testo è composto da due caratteri in realtà: \r e \n.
Gli spazi all'inizio te li dovrebbe ignorare atof. |
![]() |
![]() |
![]() |
#17 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Visto che non riesci a precalcolarti la dimensione dei gruppi da byte da leggere contemporaneamente allora ti consiglio anche io di leggerti un byte alla volta.
L'algoritmo è semplice: 0. NuovaParola = 0, Buffer contiene la stringa da convertire, N = 0 1. Car = Leggi un byte 2. Siamo alla fine del file ? Sì: vai al punto 5 3. Il Car è uno spazio o uno \r o uno \n: Se NuovaParola == 1 allora: esegui ConvertiInDouble(Buffer, N), NuovaParola = 0, N = 0 4. Per qualsiasi altro carattere: NuovaParola = 1, Buffer[N] = Car, N++ 5. fine ConvertiInDouble(Buffer, N) sarà semplicemente così: 1. Buffer[N] = '\0' 2. converto Buffer in double e lo aggiungo alla mia struttura dati Ovviamente se devi tenere conto della colonna l'algoritmo sopra va modificato, ma è semplice. Edit: poi di fatto è una macchina a stati con soli 2 stati ![]() Ultima modifica di cionci : 30-11-2008 alle 09:38. |
![]() |
![]() |
![]() |
#18 |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Grazie cionci per i passi da seguire. Ho fatto un programmino in base alle tue istruzioni, mi manca sola la funzione ConvertiInDouble. La faccio con atof? Grazie.
Edit: Non va ![]() Mi sa che il ciclo while non va bene. Codice:
#include <stdio.h> #include <stdlib.h> #define fnINPUT "vento.dat" int ConvertiInDouble(char *buffer, double *vettore, int cont) { buffer[15]='\0'; vettore[cont]=atof(buffer); return 1; } int main() { FILE *fdati; char car; int i,NuovaParola, N, lSize, cont, t, punti; char *buffer; double *vettore, **matrice; int colonne=7; lSize=16;//i numeri sono costituiti da 12 cifre piu segno, più "e"sponente e relativo segno. Che ne dici? buffer = (char*) calloc(sizeof(char),lSize); i=0; NuovaParola=0; N=0; cont=0; fdati=fopen(fnINPUT,"r"); vettore=(double *)calloc(1,sizeof(double)); while(fread(&car,sizeof(char),1,fdati)==1)// è giusto? { if(car=='\r'||car=='\n'||car==' ')//lo spazio lo leggo cosi? if(NuovaParola==1) { ConvertiInDouble(buffer, vettore, cont); cont++; vettore=(double *)realloc(vettore,(cont+1)*sizeof(double)); NuovaParola=0; N=0; } else { buffer[N]=car; N++; NuovaParola=1; } } punti=cont/7; matrice = (double **)calloc(punti,sizeof(double *)); if(matrice==NULL) printf("Righe matrice - Memoria esaurita!\n"); for(t=0; t<punti; t++) { matrice[t] = (double *)calloc(colonne,sizeof(double)); if(matrice[t]==NULL) printf("Colonne matrice - Memoria esaurita! t= %d\n",t); } for(t=0;t<punti;t++) for(i=0;i<colonne;i++) matrice[t][i]=vettore[i+t*colonne]; for(t=0;t<10;t++){ for(i=0;i<colonne;i++) printf("matrice[%d][%d]=%le\t",t,i,matrice[t][i]); printf("\n"); } system("PAUSE"); return 1; }
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." Ultima modifica di salvodel : 30-11-2008 alle 12:27. |
![]() |
![]() |
![]() |
#19 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Dunque il numero delle colonne è variabile? Nel primo esempio ci sono due numeri per riga; nel secondo sono di più.
Un esempio di automa per un problema simile al tuo: http://www.hwupgrade.it/forum/showthread.php?t=1816511 ![]() |
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Dec 2004
Messaggi: 783
|
Quote:
![]() Grazie
__________________
"May the wind always be at your back and the sun upon your face. And may the wings of destiny carry you aloft to dance with the stars...." |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 19:21.