C: mi sovrascrive su altri dati

_prime_number
devo salvare dei dati in un file... Se l'utente chiede di non sovrascrivere invio il putnatore alla fine del file, ma alla fine in realtà mi sovrascrive. Vedete il problema voi?
Grazie!

Paola
if ((fileout=fopen(file, "r"))!=NULL)           
 label:
  printf("\nIl file non è vuoto. Sovrascrivere? (y/n)");
  scanf(" %c", &risposta);
  fileout=fopen(file,"w");                   
  if (risposta=='y')
  fseek(fileout, 0, SEEK_SET);
  else
  {if (risposta=='n')
    {
     fseek(fileout, 0, SEEK_END);
     
    }
  
    if(risposta!='n' && risposta!='y')
    {
    printf("\nErrore!\n");
    goto label;
    }
    
  }
[/code]

Risposte
lorven
Cambia modalità della open in w+ o r+ invece di w, che sovrascrive comunque.

:-)

_prime_number
Non pare essere quello il problema! Ho cambiato in r+ e w+ entrambi ma sovrascrive di nuovo.. eppure nn mi pare ci sia un errore nel codice!

Paola

lorven
Dimenticavo: non credo si possa aprire nuovamente lo stesso file, se non dopo averlo chiuso. E si potrebbe usare anche la modalità di apertura in append, "a"

:-)

_prime_number
Quindi dopo averlo aperto in modalità read dovrei chiuderlo e riaprirlo in modalità write+? Cos'è la modalità append? cosa farebbe così?
Grazie!!
Paola

lorven
Esatto, prima di riaprire un file è necessario chiuderlo.
La modalità di apertura in append consente di "appendere", cioè aggiungere alla fine, altri dati al file, senza quindi dover usare la fseek.

:-)

_prime_number
ah interessante!! la provo subito!!! saperlo prima, mi sarebbe stata utile in altre situazioni!! Ti so dire se ho problemi, grazie!!

Paola

_prime_number
come non detto!! ho provato sia con la modalità append senza chiudere il file, sia chiudendolo, sia in w+ chiudendo prima il file!! :S

Lancio un'ipotesi: non è che fseek posso usarlo solo in modalità read? è forse per quello che non me lo invia alla fine del file?

paola

groucho1
no è tecnicamente esatto che bisogna per forza chiudere un file prima di riaprirlo...

FILE * freopen (const char * filename , const char * mode , FILE * stream);


altrimenti che l'hanno messa a fare questa funzione? :wink:

int exit=0;

if ((fileout=fopen(file, "r"))!=NULL)           
    while (exit==0) {
        printf("\nIl file non è vuoto. Sovrascrivere? (y/n)");
        scanf(" %c", &risposta);
        if (risposta != 'n' || risposta != 'y') {
            printf("ERRORE: risposta errata, prego inserire o "y" o "n" come risposta...\n\n");
            continue;
        }
        freopen(file, (risposta=='n') ? "a+" : (risposta=='y') ? "w+" : "r+", fileout);
        exit=1;
    }
}


l'ho scritta un po' veloce senza ricontrollare o provare a compilare... se non dovesse funzionare dimmelo che la riscrivo ^^

_prime_number
Grazie mille! In realtà ho provato a cercare la funzione reopen che mi hai dato tu in internet e ho visto che esiste la modalità a+ che legge e scrive su file (e crea il file se non esiste). E' perfetta, cosaì non devo riaprire e chiudere!! ho provato e va!

Vi ringrazio!

Paola

lorven

no è tecnicamente esatto che bisogna per forza chiudere un file prima di riaprirlo...

Reopen equivale a Close+Open...

:-)

eugenio.amitrano
Ecco una funzione richiesa di conferma "abbastanza" pulita (ho preso spunto dalle precedenti risposte) e come si usa:

#include <conio.h>
#include <stdio.h>

enum { __NO, __YES };

void beep(void) { printf("\a"); }

int getConfirm(const char * __sMessage)
{
   char __retCH;
   int __exit;

   printf("\n%s (s/n) ", __sMessage);

   do {
      __exit = 1;
      __retCH = getch();
      if(__retCH != 's' &&
         __retCH != 'S' &&
         __retCH != 'n' &&
         __retCH != 'N')
      {
         __exit = 0;
         beep();
      }
   } while (!__exit);

   if (__retCH == 'n' || __retCH == 'N')
      return __NO;
   else
      return __YES;
}

void main(void)
{
   int sel;

   clrscr();

   sel = getConfirm("Salutare ?");
   if(sel)
      printf("\n\nBUONGIORNO!");

   printf("\n\nPremere un tasto per uscire.");
   getch();
}


ma a cosa ti serve una conferma se devi scrivere in append ? (almeno cosi' sembra trasparire)

Comunque per suggerire la migliore gestione del file occorre conoscere la finalita' del file.

Per il momento vedo per te una gestione del segunete tipo:

int ..function_write.. (const char *fileOutName, .. ..)
{
   ...
   FILE *fileOutPtr;
   ...

   if((fileOutPtr = fopen(fileOutName, "a")) == NULL)
   {
      printf("\a\nERRORE: Impossibile aprire il file %s", fileOutName);
      printf("\n\nVerificare una delle seguenti possibili cause:");
      printf("\n - Il disco in uso e' pieno;");
      printf("\n - Si sta utilizzando una memoria non scrivibile o protetta da scrittura;");
      printf("\n - Il nome del file specificato non e' corretto;");
      ...
      return .. error_code_x ..;
   }

   /* da qesto punto parte l'azione di scrittura ne file */
   ....
   ....

   fclose(fileOutPtr);
}


A presto,
Eugenio

gigilatrottola2
una domanda: se il file esiste e uno sceglie di non sovrascrivere... sceglie di non salvarlo?
in questo caso potresti...

1. aprire il file per verificare se esiste già e quindi chiudere quel puntatore.
2. aprirne un altro e, se l'utente vuole sovrascrivere, allora aprire il file in scrittura. nel tuo codice noto che tu lo apri in scrittura ancor prima di sapere cosa intende fare l'utente. Se l'apertura la fai dentro l'if sei sicuro che l'else non fa danni, visto che non puo accedere a quel segmento di codice.

eugenio.amitrano
Ciao Gigi,
scusami, ma non mi e' chiaro a chi ti rivolgi.
Perdonami se posso sembrarti egocentrico pensando che ti rivolgi a me, comunque, se cosi' fosse ti chiedo di essere un po' piu' chiaro.

Eugenio

gigilatrottola2
Ah no scusa, mi riferivo a chi ha aperto il topic :)

eugenio.amitrano
;-)

groucho1
"lorven":

no è tecnicamente esatto che bisogna per forza chiudere un file prima di riaprirlo...

Reopen equivale a Close+Open...

:-)


hai ragione lorven... il mio italiano è pessimo! :lol:
intendevo... non c'è bisogno di fclose() per forza :-D

sorry per il disguido lessicale :wink:

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