Newsgroup: it.comp.lang.c++
Titolo: Lettura da file di caratteri inesistenti!

Salve,
avrei questo problema molto semplice da esporre e spero altrettanto semplice
da risolvere.
Ho il seguente file di testo chi si chiama "input.txt" il quale contiene
quanto segue (i commenti tra parentesi angolari non ci sono pero' :)
<Inizio file "input.txt">
ABC e' stato sconfitto in guerra da DEF
Questa riga serve solo a testare il programma e verra' saltata
Anche questa
DEF e' stato sconfitto in guerra da ABC
<Fine file "input.txt">
Inoltre ho il seguente sorgente in C++
<Inizio file "read.cpp">
#include <fstream>
#include <string>
#include <map>
using std::string;
pair<string, string> ElaboraStringa (string s) {
 int i = s.find("e\' stato") - 2;
 pair<string, string> PV;
 string perdente = "", vincitore = "";
 while (s[i] != ' ') {
  perdente = s[i] + perdente;
  i--;
 };
 i = s.find("in guerra da") + 13;
 while (s[i] != ' ') {
  vincitore += s[i];
  i++;
 };
 PV.first = perdente;
 PV.second = vincitore;
 return PV;
};
void ElaboraLog() {
 pair<string, string> temp;
 pair<int, int> zero;
 string s = "";
 ifstream infile("input.txt", ios::in);
    zero.first = 1;
    zero.second = 2;
 do {
  getline (infile, s, '\n');
  if (s.find ("in guerra da") != string::npos) {
   temp = ElaboraStringa(s);
            std::cout << "Perdente: " << temp.first << "Vincitore: "
            << temp.second << std::endl;
  };
    }
 while (!infile.eof());
 infile.close();
};
int main () {
 ElaboraLog();
 std::cout << "\nPremi Invio" << std::endl;
    while(std::cin.get() != '\n');
 return 0;
}
<Fine file "read.cpp">
In pratica il sorgente legge dal file considerando solo le righe in cui
appare la frase "in guerra" dopo di che chiama la funzione ElaboraStringa
per estrarre dalla frase chi e' stato sconfitto e chi invece ha vinto.
In pratica l'output dovrebbe essere il seguente:
Perdente: ABC Vincitore: DEF
Perdente: DEF Vincitore: ABC
Invece l'output e' il seguente, ovvero stracolpo di caratteri assurdi e
inesistenti:
Perdente: DEF                         '   @           ABCVincitore: DEF
Ą V @           DEF                         Ą V @           DEF
/   @           DEF                         '   @           ABC
  V 
` V 
° V 
V 
P
V 
V 
š
V 
@ V 
  V 
ą V 
0 V 
€ V 
Š V 
Perdente: saltata  '   @           DEFVincitore: ABC
Ą V @           ABC                         Ą V @           ABC
/   @           DEF                         '   @           ABC
  V 
` V 
° V 
V 
P
V 
V 
š
V 
@ V 
  V 
ą V 
0 V 
€ V 
Š V 
Ora mi chiedo: ma da dove diavolo sbucano quei caratteri? Devo forse pulire
il buffer ad ogni ciclo (se si come?) o altro?
Uso Dev-C++ 4 il quale come compilatore usa cpp.exe e g++.exe (forse sono i
porting del gpp per Linux, ma se non ricordo male quello e' il DJGPP, che
tra l'altro ho provato anche e mi da ugualmente problemi). L'OS e' windows
98.
Ho pensato che il problema potesse essere legato anche all'OS perche' tempo
fa scrissi un programmino che su Linux (che adesso non ho installato quindi
non chiedetemi di provare :) girava alla grande senza problemi (compilato
con g++) mentre su windows 98 lo stesso identico sorgente compilato con il
DJGPP generava un exe non perfettamente funzionante, ovvero algoritmicamente
era ok ma anche qui ad ogni "sessione di gioco" (leggi esecuzione di un
ciclo while) mi stampava caratteri che non centravano UNA MAZZA!. Pero' il
programma di cui parlo non leggeva ne scriveva su file... ma secondo me o il
compilatore o il sistema operativo (piu' probabile imho) e' in buona
(tutta?) parte la causa di tale problema.
Riassumendo: il problema e' la lettura di caratteri strani che nel file non
esistono!
Grazie

 da risolvere.
Eccoti la versione corretta:
#include <fstream>
#include <string>
#include <map>
using std::string;
using std::pair;
using std::ifstream;
using std::ios;
pair<string, string> ElaboraStringa (string s) {
 int i = s.find("e\' stato") - 2;
 int len = s.length();
 pair<string, string> PV;
 string perdente = "", vincitore = "";
 while (s[i] != ' ' && i >= 0) {
  perdente = s[i] + perdente;
  i--;
 };
 i = s.find("in guerra da") + 13;
 while (s[i] != ' ' && i < len) {



EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg

   i++;
Ecco! Ho notato l'errore! In pratica nel file la stringa estratta non
iniziava ne terminava con uno spazio quindi il while non si fermava. Cavolo
che sbaglio stupido! Con la tua condizione invece si ferma prima che finisca
la stringa. Pero' mi sorge una domanda:
ho provato a modificare il codice in questo modo:
  int len = s.length();
  pair<string, string> PV;
  string perdente = "", vincitore = "";
  // Nuove istruzioni
  s.insert (0, " ");
  s.append (" ");
  // Elimino la condizione i >= 0
  while (s[i] != ' ') {
   perdente = s[i] + perdente;
   i--;
  };
  i = s.find("in guerra da") + 13;
  // Elimino la condizione i < len
  while (s[i] != ' ') {
   vincitore += s[i];
   i++;
Ma non funziona. Avendo aggiunto uno spazio all'inizio e alla fine, la
condizione s[i] != ' ' non dovrebbe essere sufficiente?
Ho provato a inserire lo spazio all'inizio e alla fine direttamente nel file
e funziona anche senza le 2 condizioni (i >= 0 e i < len) ma se inserisco
gli spazi nella stringa estratta non dovrebbe funzionare lo stesso?
Altrimenti, potresti spiegarmi a cosa servono quelle 2 condizioni da te
aggiunte?
Grazie

 aggiunte?
A fermare la ricerca quando si è giunti all'inizio o alla fine della
stringa senza trovare lo spazio.


 i *dopo* aver inserito gli spazi e non prima.
Ah, si ora ho visto pero... anche se inserisco gli spazi dopo l'istruzione:
int i = s.find("e\' stato") - 2;
perche' non dovrebbe funzionare?
In pratica non dovrebbe essere cosi':
supponiamo che la stringa sia
Pippo e' stato sconfitto in guerra da Pluto
il valore di i sara' 6 - 2 = 4 (se non ho sbagliato a contare)
Inserisco gli spazi.
La lettura con il ciclo while parte dalla 'o' di Pippo e va a ritroso
finche' non trova lo spazio che ho gia inserito.
Cosa sbaglio?
Grazie

 finche' non trova lo spazio che ho gia inserito.
Vero, inserendo lo spazio la lettura inizia dalla terza 'p' di Pippo :)
Cmq, grazie per gli aiuti.

 Cmq, grazie per gli aiuti.
Di niente.


 Non ho capito, significa che hai risolto?
Si, in pratica ho visto dove sbagliavo a pensare che inserendo gli spazi
dopo il calcolo della i avrebbe dovuto funzionare lo stesso. Infatti cosi
facendo il calcolo della funzione find viene sfalsato di una posizione, ma
non l'avevo notato. In pratica quando mi hai detto di metterle prima del
calcolo della "i" avevo capito che dovevo mettere le istruzioni prima dei
cicli while e non prima di s.find()... avevo capito male.
Ciao