|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Junior Member
Iscritto dal: Jul 2009
Messaggi: 13
|
[C] I/O su file
Sì, lo so che internet è pieno di guide e topic che riguardano l'argomento, ma nessuno dei molti che ho guardato mi andava bene.
1) C'è un qualche modo per poter scrivere su un file ad una riga precisa? Sto finendo un progetto per l'università, e volevo aggiungere al mio programma un file txt per memorizzare le impostazioni del programma. Per ora pensavo a qualcosa di semplice, tipo un numero per ogni impostazione, tutti separati da un 'a capo'. Il problema a questo punto è che se mentre eseguo il programma vado a cambiare l'impostazione che viene memorizzata nella seconda riga del file settings.txt, non so come fare per modificare solo quella. 2) C'è un modo per leggere da un file una riga precisa? Attualmente, nel mio progetto, ho adottato questa soluzione: Codice:
//il numero della riga del file che devo leggere è memorizzata in 'sel'
int i = 0;
while(i <= sel) //finché i è <= della riga che ho scelto...
{
fscanf(file, "%s", s);//...salva in s la parola della riga corrente
i++;
}
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12962
|
Secondo me ti conviene fare in modo di usare impostazioni del tipo
CHIAVE = VALORE Magari ognuna su una linea per facilitare la lettura. Poi le coppie (chiave, valore) puoi metterle all'interno di una mappa. In questo modo per altro non vincoli l'utente a mettere le impostazioni in un ordine particolare. |
|
|
|
|
|
#3 |
|
Junior Member
Iscritto dal: Jul 2009
Messaggi: 13
|
Preferivo non usare, per ora, il metodo "chiave=valore" per evitare di dover estrarre ogni volta il valore: se tengo solo un numero l'accesso è più immediato, infatti io so già che il numero della prima riga si riferisce a una cosa, quello della seconda ad un'altra e così via.
edit: non ho capito se la tua risposta si riferiva anche alla mia seconda domanda |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: May 2001
Messaggi: 12962
|
Quote:
Chiaramente facendo così non ti serve andare a pescare una riga in particolare. |
|
|
|
|
|
|
#5 |
|
Junior Member
Iscritto dal: Jul 2009
Messaggi: 13
|
Ma il punto non è quello, anche perché il caricamento posso farlo una volta sola anche se uso il mio metodo.
Per ora il primo problema l'ho risolto facendo sì che ogni volta che viene modificata un'impostazione vengono riscritte anche quelle che sono rimaste uguali (se l'utente modifica un'impostazione, viene riscritto il file settings.txt). Il secondo problema invece è che devo andare a leggere una precisa riga all'interno di un txt che contiene 280.000+ parole (divise da 'a capo'), e stavo cercando una soluzione più elegante di quella che ho scritto prima (che consiste praticamente nel leggerle tutte finché non arrivo alla riga che volevo io). |
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Dec 2010
Messaggi: 74
|
ma sentito parlare delle funzioni seek o lseek che muovono il cursore all'interno del file?
__________________
Scheda Madre : Asus P6T SE | Chipset : Intel X58 | Processore : Intel Core i7 920 @ 2666MHz | Memoria Fisica : 6144MB (3 x 2048 DDR3-SDRAM ) | Scheda Video : ATI Radeon HD 4890 Series | Hard Disk : Seagate STM3500418AS ATA Device (500GB) | DVD-Rom Drive : Optiarc DVD RW AD-7240S | Tipo Monitor : Nissei Sangyo L5AK6 - 15 pollici |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Io ho un problema analogo.
Ho una matrice che si modifica con l'esecuzione del programma... Ogni modifica deve essere scritta su file. Al termine del programma, in cima al file, devo scrivere del testo . Il problema è che se torno indietro con fseek ( o rewind ) quando vado a scrivere mi va a cancellare x caratteri, tanti quanti sono i caratteri da scrivere... Di conseguenza mi cancella parte della matrice... Si può facilmente ovviare a questo mio problema aggiungendo \n a sufficienza all'inizio del file. È chiaro però che non è una soluzione molto bella... Una soluzione sarebbe quella di memorizzare la matrice modificata dentro una linked list e fare un nuovo nodo ad ogni modifica della matrice. Poi stampare il testo e a seguire ogni nodo della linked list. Lo voglio evitare... C'è altro modo? Segue un esempio del file: Codice:
Testo Matrice passo 1 Matrice passo 2 ... Matrice passo X
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Scusa, perchè non puoi/vuoi mettere il testo in coda alle modifiche della matrice?
Oppure potresti spezzare il file in due file diversi: uno per la matrice e sue modifiche, l'altro per il testo. Oppure in tre file (sto immaginando a cosa ti possono servire, e tiro a indovinare): - file con la sola matrice originale; - file con le modifiche relative alla matrice - file con il testo relativo alla matrice
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Se invece è limitabile, riservi all'inizio del file un tot di spazio solo per il testo: durante l'esecuzione del programma, le modifiche alla matrice le memorizzi in append al file, mentre al termine del programma, se il testo è stato editato, sovvrascrivi la porzione iniziale riservata del file con il testo stesso. Puoi riempire lo spazio riservato al testo con il carattere nullo '\0'.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Ho risolto mediante la funzione tmpfile() .
La matrice la memorizzo nel file temporaneo, poi quando ho finito, scrivo il testo e ricopio dal file temporaneo la matrice!
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Jan 2008
Messaggi: 8406
|
concordo con banryu, il formato del tuo file non ti consente di ricavare il numero di righe di testo dall'offset sul file
non puoi dire che il byte 398423 corrisponde sicuramente all'inizio della riga 20948 è per questo motivo che i database usano gli indici |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
però tutto dipende dal fatto di avere o non avere un limite fisso di dimensione disponibile per il testo. P.S.: Io partivo dal presupposto che il programma, avviandosi, deve leggere il file per inizializzare la matrice; in pratica il file contiene lo storico di tutte le modifiche fatte ad una matrice originale che viene modificata e ricorda il suo stato e le varie transizioni per sempre (o almeno finchè esiste detto file
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#14 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Continuo a non capire come vuoi risolvere tu il problema... A me sembra efficientissima questa soluzione, poichè: - Il file finale viene modificato una e una sola volta ( aperto -> modificato -> chiuso ) - Il file temporaneo viene aperto una volta, ogni modifica viene messa in coda al file ( come è giusto che sia ) e, al termine delle modifiche, viene copiato tutto dentro il file finale di output. Il file temporaneo viene chiuso e cancellato.
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#15 |
|
Junior Member
Iscritto dal: Jul 2009
Messaggi: 13
|
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Non puoi anche tu fare come ho fatto io? Ovvero usare la funzione tmpfile(), ti salvi tutte le impostazioni su questo file temporaneo, e poi quando hai terminato, le sovrascrivi a quelle che ci sono già sul file
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#17 |
|
Junior Member
Iscritto dal: Jul 2009
Messaggi: 13
|
Per la scrittura delle impostazioni non c'è problema, visto che sono solo 2 le riscrivo ogni volta che avviene una modifica, ma io stavo chiedendo se c'era un modo più elegante per leggere una riga precisa da un file rispetto a quello che ho messo nel primo post.
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Jan 2008
Messaggi: 8406
|
Quote:
l'indice ovviamente ha senso se occupa uno spazio che è una frazione del contenuto indicizzato, in quel caso lo si legge tutto in memoria e lo si usa da lì oppure potresti benissimo imporre che ogni riga ha una dimensione in bytes fissa ( ovviamente è la dimensione massima che un'opzione può raggiungere )....i bytes extra li riempi di zero, però almeno così può crearti una formula semplice semplice per convertire offset <--> numero di riga |
|
|
|
|
|
|
#20 |
|
Member
Iscritto dal: Dec 2010
Messaggi: 74
|
ma in che ambiente fai girare il tutto?
__________________
Scheda Madre : Asus P6T SE | Chipset : Intel X58 | Processore : Intel Core i7 920 @ 2666MHz | Memoria Fisica : 6144MB (3 x 2048 DDR3-SDRAM ) | Scheda Video : ATI Radeon HD 4890 Series | Hard Disk : Seagate STM3500418AS ATA Device (500GB) | DVD-Rom Drive : Optiarc DVD RW AD-7240S | Tipo Monitor : Nissei Sangyo L5AK6 - 15 pollici |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 16:42.




















