PDA

Visualizza la versione completa : Problema con rename e remove in c


cri336
19-01-2009, 10:49
Ciao a tutti,

ho la necessità di fare una funzione in c che preso in input un nome, deve cancellare la riga da un file contente tale parola. La soluzione adottata è quella di usare un file temporaneo.
Quello che faccio è aprire in lettura il file originario, lo copio riga per riga nell'altro file (tranne ovviamente la riga da cancellare), che precedentemente avevo aperto in scrittura, chiudo entrambi i file, cancello il file originale e rinomino il file temporaneo con il nome del file originario. Tuttavia sebbene il ragionamento sembra funzionare non capisco perchè non mi cancella il file originale e se tento di aprirlo mi esce un alert con scritto "Accesso Negato". Cosa c'è che non va? Per migliore comprensione vi posto anche il codice:




int disconnetti(char u[]){
char buffer[MAXLINE],utente[MAXLINE],nome[MAXLINE];
FILE *f;
FILE *new;

f=fopen("connessi.txt","r");
new=fopen("newconnessi.txt","w");

if (f==NULL) {
printf("Errore nell'apertura del vecchio file");
return ;
}
if (new==NULL){
printf("Errore nell'apertura del nuovo file");
return ;
}
while ((fgets(buffer,sizeof(buffer),f))!=NULL){
sscanf(buffer,"%s",utente);
if(strcmp(u,utente)!=0)
fprintf(new,"%s\n",buffer);
}

fclose(f);
fclose(new);
if ((remove("connessi.txt")) || (rename("newconnessi.txt","connessi.txt")) ){
printf("ERRORE!!!");
return 0;
}
return 1;
}

cri336
20-01-2009, 10:17
Ciao a tutti,

non avendo risposta al precedente post e non riuscendo a trovare l'errore commesso, ho adottato un'altra soluzione che posterò tra un momento... E restando in attesa per una risposta dell'altro post (ormai è diventata una questione di principio) vorrei chiedervi: tra le due quale è la più efficiente?


void disconnetti(char u[]){
char buffer[MAXLINE],utente[MAXLINE];
FILE *f, *new;
f=fopen("connessi.txt","r");
if((new=tmpfile())==NULL) //crea il file temporaneo
err_sys("Cannot creat filetemp");
if (f==NULL) {
printf("Errore nell'apertura del vecchio file");
return ;
}
while ((fgets(buffer,sizeof(buffer),f))!=NULL){
sscanf(buffer,"%s",utente);
if(strcmp(u,utente)!=0)
fprintf(new,"%s",buffer);
}
fclose(f);

fseek(new,0,SEEK_SET);
if((f=fopen("connessi.txt","w"))==NULL) //il file viene chiuso e riaperto
err_sys("open 2 error");
while ((fgets(buffer,sizeof(buffer),new))!=NULL){
fprintf(f,"%s",buffer);
}
fclose(f);
fclose(new);
}

Quello che faccio qui, è copiare dal file originario al file temporaneo e dal temporaneo all'originario (troncando la lunghezza del file originario a zero).

Se avete una soluzione migliore... Fatemi sapere! Grazie in anticipo

oregon
20-01-2009, 13:33
Non eseguire il rename e il remove nella stessa if ...

Esegui PRIMA una if con il remove e DOPO un'altra if con il rename

cri336
20-01-2009, 16:20
Ciao grazie di aver risposto,

Ho provato anche questo ma alla fine ho sempre lo stesso problema... ovvero il file connessi.txt nn viene cancellato e se tento di accedere mi da accesso negato. Però al posto della remove, ho tentato con unlink e il file viene cancellato ma cmq la remane nn viene effettuata... è come se esistesse sempre un riferimento del file connessi.txt... Infatti se nella rename metto un altro nome di file che nn esiste la rename viene fatta :bhò:

oregon
20-01-2009, 17:25
Mostra il codice dopo che lo hai modificato come ti ho detto ...

cri336
20-01-2009, 17:57
Ecco il codice:

int disconnetti(char u[]){
char buffer[MAXLINE],utente[MAXLINE],nome[MAXLINE];
FILE *f;
FILE *new;

f=fopen("connessi.txt","r");
new=fopen("newconnessi.txt","w");

if (f==NULL) {
printf("Errore nell'apertura del vecchio file");
return ;
}
if (new==NULL){
printf("Errore nell'apertura del nuovo file");
return ;
}
while ((fgets(buffer,sizeof(buffer),f))!=NULL){
sscanf(buffer,"%s",utente);
if(strcmp(u,utente)!=0)
fprintf(new,"%s\n",buffer);
}

fclose(f);
fclose(new);
if (remove("connessi.txt")!=0){
printf("ERRORE nella remove!!!");
return 0;
}
if (rename("newconnessi.txt","connessi.txt")!=0) {
printf("ERRORE nella rename!!!");
return 0;
}
return 1;
}

dà errore nella rename... ma il file connessi.txt è sempre presente e non posso accedere perchè da accesso negato.

Da qualche parte ho anche letto che il file deve essere chiuso prima di poter fare la remove o la rename cmq in ogni caso dà errore.

oregon
20-01-2009, 18:18
Scusa, ma come fai a compilare questo codice? Ci sono degli errori in compilazione ...

Intanto non devi usare una variabile che si chiami new e poi la funzione disconnetti deve restituire sempre un valore in tutte le return ...

cri336
20-01-2009, 18:44
A me nn dà errori in fase di compilazione cmq ho fatto le modifiche che mi hai detto e
si ferma in quel if della rename....

Ti posto nuovamente il codice modificato:

int disconnetti(char u[]){
char buffer[MAXLINE],utente[MAXLINE],nome[MAXLINE];
FILE *f;
FILE *new1;

f=fopen("connessi.txt","r");
new1=fopen("newconnessi.txt","w");

if (f==NULL) {
printf("Errore nell'apertura del vecchio file");
return 0;
}
if (new1==NULL){
printf("Errore nell'apertura del nuovo file");
return 0;
}
while ((fgets(buffer,sizeof(buffer),f))!=NULL){
sscanf(buffer,"%s",utente);
if(strcmp(u,utente)!=0)
fprintf(new1,"%s",buffer);
}

fclose(f);
fclose(new1);
if (remove("connessi.txt")!=0){
printf("ERRORE nella remove!!!");
return 0;
}
if (rename("newconnessi.txt","connessi.txt")!=0) {
printf("ERRORE nella rename!!!");
return 0;
}
return 1;
}

oregon
20-01-2009, 18:52
Se lavori con Windows, ottieni l'errore dopo la chiamata della rename con una GetLastError()

cri336
20-01-2009, 19:10
non lavoro in windows, sto usando cygwin in windows per compilare il programma... ma il programma è fatto per lavorare su linux...

Loading