[C] Lettura file

MyMaster
Salve a tutti,
mentre mi cimentavo in alcune esercitazioni sul C mi sono capitate più richieste del tipo:
"leggere un file di cui non si conoscono il numero di righe e......", ciò che mi crea problemi è proprio
la prima parte, perché quello che in genere faccio è crearmi un array di struct e dargi arbitrariamente
una dimensione molto grande del tipo 100000 (che rappresentano il numero di righe massimo), poi
aprire il file, copiare i dati del file in questo array di struct, chiudere il file e lavorare sul problema con
l'array di struct prima definito, quindi ho una cosa di questo tipo:
...
#define M 100000
struct data {
    char dato1[n_random];
    char dato2[n_random];
    char dato 3[n_random];
};
int main (int argc, char *argv[]) {
    ...
    struct data file1[M];
    ...
}


Siccome il professore non ha spiegato l'allocazione dinamica, secondo voi questo approccio è corretto?

Risposte
vict85
Si e no. Molto dipende dal problema che stai risolvendo. Per esempio, se vuoi calcolare la media degli elementi inseriti, non è necessario memorizzare l'input. Tieni inoltre a mente che non è strettamente necessario leggere l'intero file in una sola volta. Quindi, per alcuni problemi, potrebbe avere senso leggere gli elementi in gruppi di dimensione fissa.

Per problemi in cui abbia senso copiare in memoria l'intero file, o nel caso in cui si decida di farlo per altre ragioni, quello che proponi ha senso, ma non viene molto usato al di fuori del mondo embedded (e anche lì sempre meno). Tieni conto che usare una quantità molto grande dello stack può portare a stack overflows. Quindi è meglio non allocare 100000 elementi e poi chiamare una funzione ricorsiva su di loro.

Sinceramente, per problemi che incontri in corsi universitari, userei un valore di M molto inferiore.

Cos'è [inline]n_random[/inline]?

MyMaster
Innanzitutto grazie per la risposta,
"vict85":
per alcuni problemi, potrebbe avere senso leggere gli elementi in gruppi di dimensione fissa.

in genere i problemi che ci vengono dati richiedono una lettura intera del file, quindi non so quanto leggerlo a gruppi possa andare bene

"vict85":
Per problemi in cui abbia senso copiare in memoria l'intero file, o nel caso in cui si decida di farlo per altre ragioni, quello che proponi ha senso, ma non viene molto usato al di fuori del mondo embedded (e anche lì sempre meno).

Io ero giunto ad una soluzione di questo tipo perché il prof non vuole che si facciano operazioni (finalizzate a risolvere il problema) con il file aperto, quindi ho pensato di aprirlo, salvare i dati e chiuderlo

"vict85":
Cos'è [inline]n_random[/inline]?

n_random sarebbe la dimensione (data sempre per mezzo di una define) delle stringhe che vale 8

vict85
Se tutti i dati sono stringhe puoi anche copiare l'intero file in una grande stringa. Il caricamento del file risulterebbe anche un po' più efficiente. Comunque il tuo approccio va bene per l'esame di informatica.

Per il futuro, o userai l'allocazione dinamica o dovrai analizzare il problema con il microscopio perché ogni byte in più può essere troppo. Ma sono cose che imparerai più in là.

MyMaster
"vict85":
Se tutti i dati sono stringhe puoi anche copiare l'intero file in una grande stringa. Il caricamento del file risulterebbe anche un po' più efficiente. Comunque il tuo approccio va bene per l'esame di informatica.

Per il futuro, o userai l'allocazione dinamica o dovrai analizzare il problema con il microscopio perché ogni byte in più può essere troppo. Ma sono cose che imparerai più in là.


Perfetto! Grazie mille del chiarimento :D

tetravalenza
Ciao,

Se viene specificato "leggere un file di cui non si conoscono il numero di righe..." significa che non sono ammesse le funzioni stat, fstat? Mi sembra non sia necessario aprire il file per usare queste funzioni.

vict85
Le funzioni a cui fai riferimento non sono funzioni standard del C. In genere, questo tipo di funzioni non sono ammesse negli esami di programmazione base, ma dipende un po' dai professori.
In ogni caso, stat e fstat non ritornano il numero di righe di un file o almeno a me non risulta che possano farlo. Come calcoleresti il numero di righe di un file contenente la divina commedia usandole?

tetravalenza
L'importante è avere la dimensione del file per preparare un buffer in memoria, di solito in questi problemi universitari si fanno ipotesi del tipo: si supponga che la dimensione del file non superi la memoria disponibile.
In caso contrario si può preparare un controllo con ulimit. Una volta che si ha caricato il buffer con qualche funzione di IO, si può procedere con le espressioni regolari oppure con un while cercando le occorrenze di '\n'.

apatriarca
@tetravalenza: nella discussione si stava chiedendo cosa fare nel caso in cui non si possa fare uso di allocazione dinamica. Senza questa condizione ci sono certamente tantissimi metodi per risolvere il problema.

Senza fare uso di memoria dinamica ci sono solo due metodi:
1. Allocare staticamente un array molto grosso.
2. Modificare l'algoritmo in modo da memorizzare solo una parte del file in memoria (di dimensione fissata) per volta.

Il metodo 2 può fare eventualmente uso di un file aggiuntivo da usare per memorizzare informazioni "per dopo". Se ci fornisci un esempio di esercizio forse possiamo darti informazioni più precise su come affrontare il problema.

tetravalenza
"apatriarca":
Se ci fornisci un esempio di esercizio forse possiamo darti informazioni più precise su come affrontare il problema.


Ciao, volevo suggerire all'utente MyMaster l'uso delle funzioni stat, fstat per aggirare il problema del numero di righe del file. Ho frainteso. Scusate.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.