Pagina 2 di 3 primaprima 1 2 3 ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 25
  1. #11
    Originariamente inviato da dosdosdos
    Il problema è che devo fare questo controllo perchè questi file devo utilizzarli su un algoritmo parallelo (con MPI) e devo essere sicuro del numero di righe per poterle partizionar ein modo corretto. Inoltre il file avrà molte molte righe!
    Be', ma voglio dire, una volta che hai letto il numero di righe indicate all'inizio del file, cosa ti importa se dopo ce ne sono di più? Ignorale, cavoli di chi ha creato il file in maniera errata.
    Avevo pensato a lavorare con la dimensione del file: se so a priori quanti Byte è lungo il file potrei dividere tale grandezza con la dimensione dei campi riga, ma ho qualche problema a capire come posso determinare la grandezza totale del file a priori.
    fseek+ftell
    Un'ultima cosa: il codice precedente lancia correttamente un errore se al posto dell'intero della dimensione si scrive un carattere, ma non riesce a gestire un intero negativo.
    Scrivendo -10 al posto di 10 ottengo:

    Il vettore contiene 4294967286 elementi.
    Segmentation fault

    ...ma è possibile che converta automaticamente il numero in unsigned?
    Credevo che con il %u fosse abbastanza furbo da evitare di cascarci... be', fai così: dichiara dimensioni come int e usa %d, e, se vedi un dimensione negativo considera il file non valido.
    Amaro C++, il gusto pieno dell'undefined behavior.

  2. #12
    Sì, è bastato dichiarare dimensioni come int e aggiungere un piccolo controllino
    codice:
    ....
    if(fscanf(fPtr,"%d",&dimensioni)!=1 || dimensioni<0 || fgetc(fPtr)!='\n')
    			printf("Errore: ...\n");
    		else {...
    per far funzionare tutto!
    Solo una piccola nota: ho eliminato il comando

    codice:
     ungetc('\n',fPtr);
    dopo aver letto la prima riga poichè non ho necessità di tornare indietro (tra l'altro tornerebbe indietro di un solo carattere)

    Ho usato le funzioni fseek e ftell come mi hai suggerito:

    codice:
    fseek(fPtr,0L,SEEK_END); 
    			int dimFile = ftell(fPtr)+1;
    			fseek(fPtr,0L,SEEK_SET); 
    			printf("lunghezza file: %d\n", dimFile);
    Solo che ho qualche problema a gestire la dimFile rtornata....non è che è colpa del fatto che il mio file non è un file binario? In tal caso dovrei sostituire le fscanf con fread e le fprintf con fwrite....giusto?

  3. #13
    Originariamente inviato da dosdosdos
    Solo una piccola nota: ho eliminato il comando

    codice:
     ungetc('\n',fPtr);
    dopo aver letto la prima riga poichè non ho necessità di tornare indietro (tra l'altro tornerebbe indietro di un solo carattere)
    In effetti si limiterebbe a rimettere il '\n' estratto per effettuare il controllo, il che non ha comunque effetto sulle successive fscanf.
    Solo che ho qualche problema a gestire la dimFile rtornata....non è che è colpa del fatto che il mio file non è un file binario? In tal caso dovrei sostituire le fscanf con fread e le fprintf con fwrite....giusto?
    No; l'apertura come file di testo ha l'unico effetto di trasformare gli eventuali ritorni a capo specifici della piattaforma (CRLF su Windows, CR e basta su Unix, LF e basta su Mac, o roba del genere) in normali '\n' durante la lettura (e viceversa in scrittura); la modalità binaria invece ti restituisce il file esattamente com'è su disco, senza applicare trasformazioni.
    La dimFile ritornata comunque se hai aperto in modalità binaria dovrebbe essere il numero di byte del file, mentre se è in modalità testo credo che vengano tolti i linefeed su Windows (per cui in questa modalità credo che sia più lento).
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #14
    Prendendo ad esempio il file postato sopra:

    codice:
    10
    2.00
    2.00
    3.00
    2.00
    4.00
    3.00
    5.00
    1.00
    1.00
    4.00
    sia che io apra il file con fopen(...,"rb") o con fopen(...,"r") la funzione

    codice:
    fseek(fPtr,0L,SEEK_END); 
    			int dimFile = ftell(fPtr)+1;
    			fseek(fPtr,0L,SEEK_SET); 
    			printf("lunghezza file: %d\n", dimFile);
    ritorna il valore 54.
    Con un po' di prove ho visto che ogni riga del file vale 5, la prima riga vale 3, più un 1 extra.
    (ma sono Byte vero??)
    E il totale ritorna: 5x10 +3 +1 = 54. Questo mi sarebbe sufficiente a capire quante righe ha un file semplicemente dividendo per 5 (senza resto) il risultato della funzione scritta sopra.
    Il fatto è che vorrei capire perchè lo fa!

    Questa strategia ha comunque un altro piccolo inconveniente: si deve gestire il numero intero in prima riga nel caso superi la dimensione di 5, altrimenti si sballa una riga!

  5. #15
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Se il file non ha tutte le righe di uguale lunghezza, questo ragionamento non ha senso e porta a risultati sballati ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #16
    Solo la prima riga del file è diversa dalle altre, le restanti sono tutte uguali e contengono un double per riga.

  7. #17
    Se uno dei double supera il 10 i calcoli ti si sballano comunque, visto che richiede più caratteri per essere scritto. Ribadisco, fidati del primo numero, e al limite fornisci un'opzione per il controllo dei file leggendo il file fino alla fine con fscanf e feof.
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #18
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da dosdosdos
    Solo la prima riga del file è diversa dalle altre, le restanti sono tutte uguali e contengono un double per riga.
    La lunghezza di un numero in un file di testo dipende dalle cifre usate prima e dopo la virgola, non è quindi "fissa" solo perchè è un double ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #19
    ho scritto i record nel file con fwrite impiegando per ogni record la dimensione di un double (8 byte). con questo programmino mi sono andato a calcolare la dim del file finale:

    codice:
    fseek(fPtr,sizeof(double),SEEK_END);
    
    int fileDimension = ftell(fPtr);
    
    printf("lunghezza file: %d\n", fileDimension/sizeof(double) );

    tutto funziona correttamente, con il piccolo problema che, qualsiasi sia la dimensione del file, il numero di record stampato è sempre maggiore di 2 rispetto a quello reale!
    In pratica risultano 2x8=16 Byte extra ... qualcuno saprebbe dirmi da dove possano provenire?

  10. #20
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,481
    Originariamente inviato da dosdosdos
    ho scritto i record nel file con fwrite impiegando per ogni record la dimensione di un double (8 byte).
    Quindi il file non è un file ASCII ma un file binario ...

    Perchè usi il sizeof in questa riga

    fseek(fPtr,sizeof(double),SEEK_END);
    ?

    Dovrebbe essere

    fseek (fPtr, 0, SEEK_END);
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.