|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Member
Iscritto dal: Apr 2010
Città: Prov. Napoli
Messaggi: 66
|
poblema quando il file la raggiunge la fine (EOF)
salve, spero possiate aiutarmi:
Ho scritto un codice che confronta, ad una ad una, ogni riga di file con tutte le righe di un altro file. Scrive la riga che non è stata trovata su un altro file. Il problema è che FINITO il secondo file vorrei che il suo puntatore cominciasse dall'inizio per un nuovo confronto. Per fare ciò ho messo a loop l'apertura e chiusura del file (cosa che dovrebbe risolvere il problema) ma non funziona. Allora sono passato ad iso::beg che dovrebbe portarmi il puntatore il cima al file--> NON FUNZIONA. Quindi mi ritrovo che fa il confronto solo della prima riga di un file. Una volta arrivato alla file, il secondo file, MUORE non è più possibile usarlo e quindi tutti i successivi risultati "risultano NON PRESENTI" e quindi scritti nel file di output o.o **********************AGGIORNAMENTO***************************** Non so cosa ho cambiato nel vecchio codice, in realtà NIENTE, ma adesso "funziona meglio": facendo altri esperimenti ho capito che il problema del non funzionamento di "ios::beg" inizia a sussistere quando il secondo file arriva per la prima volta alla fine. Da allora non è più in grado di tornare all'inizio!! P.S. ho lasciato i codici di commenti per dare un idea più chiara nel caso lo compiliate Codice:
int main(){
ifstream in1, in2;
ofstream ou;
char fr[1000], temp[1000];
bool idem=false;
in1.open("1.txt");
ou.open("risultati_assenti.txt");
in2.open("2.txt");
while(!in1.eof()) {
in1>>fr;
cout<<"\nPRENDO fr: "<<fr;
// in2.open("2.txt");
in2.seekg(0, ios::beg);
idem=false;
if (!in2.eof()) cout<<"\nENTRA";
while(!in2.eof()) {
in2>>temp;
cout<<"\nPRENDO temp: "<<temp;
if (!strcmp(fr, temp)) {
idem=true;
cout<<"\nVERO";
break;
}
}
if (idem==false) {ou<<fr<<endl; cout<<"\nSCRITTO: "<<fr;}
// in2.close();
}
ou.close();
in1.close();
in2.close();
cout<<endl;system("pause");
}
__________________
Sempre nei vostri cuori
Ultima modifica di Carmine01 : 03-03-2014 alle 21:48. |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Per favore aggiusta l'indentazione...
Non ci posso credere, nel web non ho trovato un solo esempio pulito di come si legge un file, solo le cose più assurde... Allora, o fai la lettura direttamente nella condizione del while, in modo che avvenga prima la lettura e poi viene verificato se è andata bene, oppure fai una lettura preventiva fuori ciclo come è stato fatto qui: http://hwupgrade.it/forum/showpost.p...9&postcount=27 Una volta che avrai aggiustato questi elementi di base potremo verificare il resto. |
|
|
|
|
|
#3 |
|
Member
Iscritto dal: Apr 2010
Città: Prov. Napoli
Messaggi: 66
|
Grazie della risposta, Daniels.
Questo è il codice attuale: Codice:
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "D:\Programmi\Dev\Carminefunz.cpp"
using namespace std;
const int dimstring=1000;
int main(){
ifstream in1, in2, tmp;
ofstream ou;
char fr[dimstring], temp[dimstring];
bool idem=false;
int righi1=0, conta=0, righi2=0;
cout<<"\nRinomina il file di testo che possiede tutti gli elementi utili al confronto chiamandolo:\n\"1.txt\" oppure \"1\"\nA seconda se (rispettivamente) le estensioni sono visibili o meno.\n\nRinomica il secondo file in cui POTREBBERO essere mancaze rispetto al primo:\n\"2.txt\" oppure \"2\"";
//conta i righi di un file e verifica dell'apertura dello stesso.
tmp.open("2.txt");
if (tmp.fail()) {cout<<"\n\n\nIL FILE 2/2.txt MANCA.\n"; system("pause"); exit(1);}
while (!tmp.eof()) {righi2++; tmp>>fr;}
tmp.close();
//conta i righi di un file e verifica dell'apertura dello stesso.
tmp.open("1.txt");
if (tmp.fail()) {cout<<"\n\n\nIL FILE 1/1.txt MANCA.\n"; system("pause"); exit(1);}
while (!tmp.eof()) {righi1++; tmp>>fr;}
tmp.close();
in1.open("1.txt");
ou.open("risultati_assenti_in_2.txt");
in2.open("2.txt");
while(!in1.eof()) {
in1>>fr;
//cout<<"\nPRENDO fr: "<<fr;
// in2.open("2.txt");
in2.seekg(0, ios::beg);
idem=false;
conta=0;
//if (!in2.eof()) cout<<"\nENTRA";
//fa il confronto di tutti i righi tranne l'ultimo (gl'impedisco di "arrivare alla fine")
while(conta<righi2-1) {
conta++;
in2>>temp;
//cout<<"\nPRENDO temp: "<<temp;
if (!strcmp(fr, temp)) {
idem=true;
//cout<<"\nVERO";
break;
}
}
if (idem==false) {ou<<fr<<endl;/* cout<<"\nSCRITTO: "<<fr;*/}
// in2.close();
}
ou.close();
in1.close();
in2.close();
1) "tmp.open("1.txt");" non apre il file, non lo trova, suppongo. 2) Una volta che un file viene aperto-usato-chiuso alla sua riapertura resta all'ultima posizione trovata. (Promblema, appunto, del vecchio codice). 3) (collegata alla 2) ) Quando x.eof(); da segnali positivi (perchè arrivato appunto alla fine), il file a in questione non lo si può più aprire e sperare che cominci dall'inizio, NOSSIGNORE, il puntatore resta nell'oblio più nascosto della fine del file.
__________________
Sempre nei vostri cuori
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Beh, se non crei i file necessari io posso farci poco
Comunque non hai ancora applicato un algoritmo corretto per la lettura del file. |
|
|
|
|
|
#5 |
|
Member
Iscritto dal: Apr 2010
Città: Prov. Napoli
Messaggi: 66
|
Mi sermbrava inutile specificare che il file esiste.
Per quanto riguarda la corretta applicazione della lettura di file, potresti guidarmi tu con tuoi esempi (e se sono quelli che hai linkato: non li ho capiti). Grazie per la disponibiletà e pazienza
__________________
Sempre nei vostri cuori
|
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Jul 2005
Città: Vicenza
Messaggi: 1570
|
Se devi fare più confronti perché non ti salvi tutti i caratteri dei file in un buffer in memoria e poi lavori su quello? È sicuramente più efficiente.
Inviato dal mio Nexus 5 utilizzando Tapatalk |
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Beh, dipende da quante dati ci sono nel file, immagina un file di 20GB caricato in memoria... non è molto efficiente, ovviamente dipende dall'applicazione, ma comunque aggirare un problema non vuol dire risolverlo.
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Quote:
Metodo convenzionale: Codice:
in1.open("1.txt");
in1>>fr;
while (!in1.eof()) {
// elaborazione di fr
in1>>fr;
}
Codice:
in1.open("1.txt");
while (in1>>fr) {
// elaborazione di fr
}
|
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Jul 2005
Città: Vicenza
Messaggi: 1570
|
Quote:
Gli ho consigliato un possibile e performante approcio al suo problema. È chiaro che bisogna poi vedere la sua reale situazione, quindi tutte le variabili al contorno del suo caso (che non conosciamo, se non che sta confrontando due generici file di testo). La dimensione è chiaramente una variabile da prendere in considerazione, ma per quel che ne sai e ne sappiamo quel file può essere di pochi byte come di GB (anche se dubito sia il suo caso, trattandosi di un file di testo |
|
|
|
|
|
|
#10 |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Che i dati siano pochi nel caso specifico lo sospetto anch'io, ma preferisco che quando si incontra un problema lo si risolva, e solo dopo si cerchi un'eventuale soluzione migliore, soprattutto quando il problema riguarda un'operazione comune come la lettura di un file.
Ora Carmine01 mi scaglierà contro mille fatture, ma credo sono convinto che questo sia il modo corretto di operare, altrimenti gli consiglierei un paio di comandi unix e risolverebbe con una riga di codice |
|
|
|
|
|
#11 |
|
Member
Iscritto dal: Apr 2010
Città: Prov. Napoli
Messaggi: 66
|
Kendall
I file non sono certo grandi 2GB (anche se per elaborare tutto ci mette 3 minuti).. XD quindi il tuo è un consiglio molto valido, ma come dice Daniels118, i problemi DEVONO RISOLVERSI. Ora, Daniels, non ti maledico, anzi.. ma ti esorto a guardare il codice che rispetta cio che hai scritto, il problema che non hai considerato è che mi servono 3 file FSTREAM (di cui 2 IN e 1 OUT) che lavorano simultaniamente. Quindi: è sintatticamente corretto il mio, dal tuo punto di vista? se non lo è, dove sbaglio??
__________________
Sempre nei vostri cuori
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
La sintassi è corretta, se non lo fosse la compilazione andrebbe male, quello che non è corretto è la logica, vediamo perché.
Il metodo ios::eof è equivalente alla funzione c feof di cui riporto uno stralcio della documentazione che puoi trovare qui: http://www.cplusplus.com/reference/cstdio/feof/ Quote:
Ora consideriamo il tuo algoritmo di lettura: Codice:
open(filename)
while (! eof) {
leggi
elabora
}
Utilizzando invece questo algoritmo, il controllo della fine del file avviene sempre dopo la lettura: Codice:
open(filename)
leggi
while (! eof) {
elabora
leggi
}
L'algoritmo può essere applicato ad entrambi i file innestandone uno identico dove c'è scritto "elabora". Ovviamente tutto il discorso che ho fatto si applica solo per la lettura. PS. non è che "non ho considerato", è che voglio fornirti le basi e lasciare che sia tu ad applicarle. |
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
mmap ....
__________________
GPU Compiler Engineer |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Beh, mmap consentirebbe di ottimizzare il caricamento in memoria rendendolo progressivo, ma resta di fatto che se il file ha una dimensione maggiore della memoria disponibile il sistema deve paginare, andando di fatto a lavorare su disco.
Ovviamente come nella maggior parte dei casi la soluzione migliore sta nel mezzo e una corretta analisi del problema consente di adottare la soluzione più performante. |
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
__________________
GPU Compiler Engineer |
|
|
|
|
|
|
#16 |
|
Member
Iscritto dal: Apr 2010
Città: Prov. Napoli
Messaggi: 66
|
mi sento molto stupido, adesso.
Sistemata l'operazione basilare del corretto lavoro su file. Resta il problema che non mi viene rilevato il file "1.txt" PER NON SO QUALE MOTIVO. Ho provato a usare una variabile ifstream apposita, ho provato a sostituire il file e variarlo anche nei contenuti ma mi da lo stesso errore.. Grazie per la risposta, a tutti!!
__________________
Sempre nei vostri cuori
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Quote:
|
|
|
|
|
|
|
#18 | |
|
Senior Member
Iscritto dal: Jan 2014
Messaggi: 852
|
Quote:
Fai anche molta attenzione ai percorsi dei file, i percorsi relativi fanno riferimento alla workdir, che per i programmi lanciati con doppio click è la stessa dove si trova il file eseguibile, ma se vengono lanciati da shell è la directory visualizzata sul prompt. |
|
|
|
|
|
|
#19 |
|
Member
Iscritto dal: Apr 2010
Città: Prov. Napoli
Messaggi: 66
|
Codice:
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include "D:\Programmi\Dev\Carminefunz.cpp"
using namespace std;
const int dimstring=1000;
int main(){
ifstream in1, in2, tmp;
ofstream ou;
char fr[dimstring], temp[dimstring];
bool idem=false;
int righi1=0, righi2=0;
cout<<"\nRinomina il file di testo che possiede tutti gli elementi utili al confronto chiamandolo:\n\"1.txt\" oppure \"1\"\nA seconda se (rispettivamente) le estensioni sono visibili o meno.\n\nRinomica il secondo file in cui POTREBBERO essere mancaze rispetto al primo:\n\"2.txt\" oppure \"2\"";
//conta i righi di un file e verifica dell'apertura dello stesso.
tmp.open("2.txt");
if (tmp.fail()) {cout<<"\n\n\nIL FILE 2/2.txt MANCA.\n"; system("pause"); exit(1);}
tmp>>fr;
while (!tmp.eof()) {righi2++; tmp>>fr;}
tmp.close();
//conta i righi di un file e verifica dell'apertura dello stesso.
tmp.open("1.txt");
if (tmp.fail()) {cout<<"\n\n\nIL FILE 1/1.txt MANCA.\n"; system("pause"); exit(1);}
tmp>>fr;
while (!tmp.eof()) {righi1++; tmp>>fr;}
tmp.close();
in1.open("1.txt");
ou.open("risultati_assenti_in_2.txt");
in2.open("2.txt");
in1>>fr;
while(!in1.eof()) {
//cout<<"\nPRENDO fr: "<<fr;
// in2.open("2.txt");
in2.seekg(0, ios::beg);
idem=false;
//if (!in2.eof()) cout<<"\nENTRA";
//fa il confronto di tutti i righi tranne l'ultimo (gl'impedisco di "arrivare alla fine")
in2>>temp;
while(!in2.eof()) {
//cout<<"\nPRENDO temp: "<<temp;
if (!strcmp(fr, temp)) {
idem=true;
//cout<<"\nVERO";
break;
}
in2>>temp;
}
in1>>fr;
if (idem==false) {ou<<fr<<endl;/* cout<<"\nSCRITTO: "<<fr;*/}
// in2.close();
}
ou.close();
in1.close();
in2.close();
}
Ho provato anche mettendolo nell'unita C:\ ma niente da fare
__________________
Sempre nei vostri cuori
|
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Aug 2001
Città: San Francisco, CA, USA
Messaggi: 13827
|
Quote:
Come lanci il programma?
__________________
GPU Compiler Engineer |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 23:02.



















