Newsgroup: it.comp.lang.c++
Titolo: ios::ate

Scusate, è da giorni che ci lavoro, ma non ci riesco ancora. Dovrei
aggiungere testo ad un file già esistente tramite queste due funzioni che ho
inserito in una header:
void WriteReachedScore(int position, char player[], int score)
{
  fstream file(FILE_NAME, ios::binary | ios::ate);
  //if (!file) {cout << "Impossibile memorizzare il punteggio"; getch();
return;}
  file << position << "  " << player << "                " << score;
  file.close();
  return;
}
Questa dovrebbe scrivere la roba nel file dove FILE_NAME è il nome di un
file definito come costante, mentre position, player e score sono delle
variabili contenenti dei valori.
Questa inece è la funzione che legge il file:
void ReadReachedScores(void)
{
  char name[10][20];
  int position[10];
  int score[10];
  int i;
  ifstream file("scoretable.snk");
  if (!file) return;
  clrscr();
  for (i = 0; (!file.eof()); i++)
  {
    file >> position[i];
    file >> name[i];
    file >> score[i];
  }
  for (int a = 0; a <= (i - 2); a++) printf("%d  %s           %d\n",
position[a]
                                                           , name[a],
score[a]);
  file.close();
  return;
}
In realtà il programma funziona, ma non mi aggiunge il testo. Quello che mi
appare a video è solamente una riga, ossia come se lui continuasse a
scriverci sopra. Cosa ho sbagliato?
Scusate se il post è un poco lunghetto.
Ramses

   if (!file) return;
Come sopra, questa riga non serve, la puoi sostituire con: if(file.bad())
return;
Per avere una panoramica di tutti i metodi e proprietà che puoi usare con
queste classi ti consiglio di dare un'occhiata all'header fstream.h
(dovrebbero essere tutte lì).
Cristiano

inserito in una header:
...
Hai dimenticato di mettere un separatore a fine linea
nella fase di scrittura. Quello che ti succede e' che
l'ultimo punteggio score viene scritto immediatamente
prima della posizione e in fase di lettura questi che
tu hai scritto come due campi vengono invece letti
come un valore unico.
Ti dovrebbe bastare aggiungere "\n" dopo lo score in
fase di scrittura.
Il file ti appariva come una linea unica perche' non
scrivevi mai nessun a-capo.
HTH
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

...

Correggimi se sbaglio,
allora il file in scrittura era binary e quello in lettura invece per
default era di testo quindi in scrittura bisogna creare un file
con \n come separatore per poterlo leggere come testo.
Ma si sarebbe potuto non mettere il separatore \n ed
aprire anche il file in lettura come binary ?

aprire anche il file in lettura come binary ?
No... questo e' un punto su cui e' importante non fare
confusione. La differenza fra uno stream aperto in binario
o in modo testo in DOS/Win cambia semplicemente una traduzione
del carattere di a-capo del C/C++ '\n' nella convenzione
del sistema operativo locale. Nel caso del DOS/Windows
questo carattere diventa la sequenza '\r\n' ovvero 0x0D+0x0A
(per un totale di due caratteri); in altri ambienti possono
invece succedere cose abbastanza diverse (dal generare un
solo carattere al generare un riempimento di spazi sino
al raggiungimento di una linea di lunghezza prefissata o
altro ancora) e non e' il caso di entrare in dettagli in
questo momento. Cosa sia esattamente un "file di testo"
e' qualcosa di fortemente dipendente dall'ambiente.
Il problema di quel programma era pero' in un altro
punto; quando tu usi l'operatore di redirezione "<<"
per scrivere dei numeri in un file il C++ non aggiunge
nessun separatore in automatico; questo indipendentemente
dal fatto che lo stream sia aperto in binario o in modo
testo (binario/testo sono cose che entrano in azione
in un momento successivo).
Il problema di base e' che se usi per scrivere
  f << x << y << z;
non e' detto che un sistema corretto per leggere sia
  f >> x >> y >> z;
il motivo e' che visto che in scrittura il C++ non
mette separatori anche la parte di y potrebbe finire
erroneamente per essere letta come la continuazione
della parte di x.
Nel programma erano stati messi correttamente dei
separatori fra i campi con
  f << x << " " << y << " " << z;
ma ci si era dimenticato di mettere un separatore
alla *fine della riga*.
Il risultato era che l'inizio di quella che si
sarebbe voluto essere la seconda riga veniva
interpretato come la continuazione dell'ultimo
campo della prima. Cambiando la scrittura in:
  f << x << " " << y << " " << z << "\n";
tutto dovrebbe funzionare correttamente.
In pratica il programma invece di scrivere
  123 456 789
  234 567 890
scriveva
  123 456 789234 567 890


Guarda, non so che dirvi, ringrazio sia te che Andrea per avermi spiegato
tanto, ma ancora nulla da fare. Ho applicato tutte le modifiche penso, ma la
cosa è assolutamente identica a prima, non è cambiata di uno sputo.
Questo è quello che ho scritto ora:
void WriteReachedScore(int position, char player[], int score)
{
  ofstream file("scoretable.snk", ios::binary | ios::ate);
  //if (!file) {cout << "Impossibile memorizzare il punteggio"; getch();
return;}
  file << position << "  " << player << "                " << score << "\n";
  //file.close();
  return;
}
Tra l'altro, anche inserendo "\n" (come mi ha detto Andrea) non cambia
proprio nulla visto che anche nel file testo non va a capo, mentre dovrebbe
no? Non capisco.
void ReadReachedScores(void)
{
  char name[10][20];
  int position[10];
  int score[10];
  int i;
  ifstream file("scoretable.snk", ios::binary);
  //if (!file) return;
  clrscr();
  for (i = 0; (!file.eof()); i++)
  {
    file >> position[i];
    file >> name[i];
    file >> score[i];
  }
  for (int a = 0; a <= (i - 2); a++) printf("%d  %s           %d\n",
position[a]
                                                           , name[a],
score[a]);
  file.close();
  return;
}
E questa è la main che ho usato per fare partire questo header:
#include <iostream.h>
#include "score.h"
#include <conio.h>
#include <stdio.h>
void main(void)
{
  WriteReachedScore(1, "Luca", 1235);
  ReadReachedScores();
  getch();
  return;
}
Basta, il programma è tutto qui. Grazie cmq, ovviamente, dell'aiuto che mi
avete dato fino ad ora.
Grazie.
Ramses

 Andrea
Grazie
Ramses

va a capo, mentre dovrebbe no? Non capisco.
Neanche io. Sei sicuro di aver fatto le prove corrette ?
Nota che il programma funziona sia che usi binary sia che
non lo usi. Semplicemente non usando binary il file prodotto
rimane un po' piu' compatibile con l'ambiente in cui fai
girare il programma (e di conseguenza riuscirai ad aprirlo
con editor di testo ma diventera' necessaria una traduzione
per trasferirlo da un sistema operativo all'altro).


 tanto, ma ancora nulla da fare. [...]
Già che ci siamo puoi tentare così:
void WriteReachedScore(int position, char player[], int score)
{
  ofstream file("scoretable.snk", ios::binary | ios::ate);
  char buf[99];
  sprintf(buf,"%d  %s                %d\n",position,player,score);
  file.write(buf,strlen(buf));
}
prova a chiamare la funzione così:
WriteReachedScore(1, "Luca", 1235);
WriteReachedScore(2, "Mario", 9876);
io ottengo questo (che dovrebbe essere quello che vorresti ottenere tu):
1  Luca                1235
2  Mario                9876
Funge? :-)
Ciao
Cristiano

Già che ci siamo puoi tentare così:
Tentare ?
Da quando in programmazione andare a tentativi e'
la cosa migliore ? Sono forse consigli da dare ?
Non esiste il tentare. Esiste il fare o il non
fare [Yoda].
Secondo me e' vero in generale nella programmazione
ma in C++ e' una regola *aurea*. Se hai le idee
confuse chiariscitele; per tentativi non farai
molta strada in C++ (anche per colpa dei terribili
demoni nasali che a spesso amano nascondersi per
colpire solo quando meno te lo aspetti).


 Andrea
Grazie ad entrambi.
Ramses

>   using namespace std;
Un'ultima cosa, qui il Borland C++ 5.02 mi da un errore.
E cmq cosa è questo std::?
Grazie
Ramses

 E cmq cosa è questo std::?
E' il namespace in cui sono dichiarati i nomi della libreria standard.
Max

prova.
Scusate non ho piu' il mio server di newsgroup e sto provando con il
posting di google.
C'e' qualcuno che mi sa dare le coordinate di un server di newsgroup
da cui accedere? Sono in Francia per cui non posso usare tiscali tin e
similari italici.
Maurus

 > E cmq cosa č questo std::?


Ramses
Perche' il compilatore che usi e' vecchio. Il concetto di
namespace e' stato introdotto relativamente di recente e
i primi compilatori C++ non supportavano questa sintassi.
Lo standard ufficiale C++ richiede che i namespace siano
implementati e oggi tutti i principali compilatori C++
li supportano decentemente.
Se ti interessa studiare il C++ ti converebbe scaricarti il
BCC 5.5.1 (disponibile gratuitamente sul sito Borland) che
dal punto di vista dello standard e' molto piu' allineato
del 5.02 che stai usando.
