Newsgroup: it.comp.lang.c++
Titolo: Ansi string da buttare?

Salve,
scusatemi se la mia domanda e' un po' (spero non completamente) da neofta.
Sto cercando disperatamente un modo per leggere un file di testo ed inserire
il tutto in stringhe tipo "string" l'ideale sarebbe poter manipolare ogni
riga del file memorizzanrla in una stringa dinamica, ma volendo se non fosse
possibile potrei pure utilizzare una sola stringa (sempre dinamica) per il
testo di tutto il file.
Il mio problema consiste nel non poter utilizzare nel mio programma nessuna
funzione C (scanf() e printf() per esempio), ho provato:
  fstream f1;
 f1.open( "file.txt",ios::in|ios::out);
 string lin;
 getline(f1,lin,'\n');
f1.close();
ma "lin " non contiene affatto il testo da me cercato.
Se faccio lo stesso con il C, vetori e "scanf(); tutto funziona bene,
posibile che il C++ debba soccombere rispetto al C?
Inoltre dovrei anche tresformare un eventuale dato numerico contenuto nella
stringa in un dato di tipo intero o float, ma non ho trovato nessuna
funzione che accetti un tipo string per effettuare la convrsione (sempre che
riesca a leggere il file di testo con string).
Esiste un modo per utilizzare l'ansi string adeguatamente per tali scopi,
oppure devo rinunciare ai vantaggi offerti (per ora visti solo sulla carta)?
buttando il tipo string, per gestire il tutto manualmente con vettori
dinamici?
Ringrazio anticipatamente chiunque abbia la cortesia di rispondermi.
Ciao.


Nessuno e' in grado di aiutarmi neanche con un semplice link? :-(((
Ciao e grazie a tutti.

posibile che il C++ debba soccombere rispetto al C?
Ne dubito. Ogni linguaggio ha le sue metodologie, tutto sta nel
comprenderle a fondo.
Quando avrai imparato bene il C++ forse capirai che con questo
linguaggio si possono avere molte più possibilità rispetto al C, le
stesse prestazioni ed una produttività decisamente maggiore.
Il Ghenio
---------
// TODO: Place your ass here

         {
Ahi, ahi - tipico errore di pascalista.  Il flag di EOF viene settato
*dopo* aver superato la fine del file, non prima.
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Dept. of Physics, Univ. of Padova, Italy          loreti at pd dot infn dot it

*dopo* aver superato la fine del file, non prima.
Sul fatto che io fossi un pascalista ci hai preso, ma spiegami in
quali casi una simile gestione potrebbe dare problemi.


 quali casi una simile gestione potrebbe dare problemi.
Beh, leggi una volta di troppo.  Tu credii di impostare un test del
genere: "fino a che la prossima lettura non dara' end-of-file esegui
il corpo del while {}"; quello che succede invece e' che viene
eseguito il corpo del while {} "fino a quando la lettura *precedente*
non ha dato end-of-file".  Quindi viene chiamata getline() una volta
di troppo; quello che succede _credo_ sia implementation dependent,
quindi (ad esempio) potrebbe tornarti indietro una stringa vuota
oppure la stringa potrebbe conservare ancora il vecchio contenuto.
Per prova, ho creato un file "in.dat" che contiene tre righe:
uno
due
tre
ed un programma (senza controlli di errore etc.) che le legge nei due
modi:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
  unsigned u = 0;
  string s;
  ifstream in1("in.dat"), in2("in.dat");
  while (getline(in2, s)) {
    cout << "Linea " << ++u << ": \"" << s << '\"' << endl;
  }
  u = 0;
  cout << "-----------------" << endl;
  while (!in1.eof()) {
    getline(in1, s);
    cout << "Linea " << ++u << ": \"" << s << '\"' << endl;
  }
}
Una volta compilato ed eseguito, il risultato e':
Linea 1: "uno"
Linea 2: "due"
Linea 3: "tre"
-----------------
Linea 1: "uno"
Linea 2: "due"
Linea 3: "tre"
Linea 4: ""


     }
Una piccola correzione che lo rende maggiormente C++ stile.
#include<vector>
#include<string>
#include<fstream>
std::vector<std::string> vs;
std::ifstream f1("file.txt",std::ios_base::in);
if(!f1)
{
    std::cerr << "Impossibile aprire il file";
    /* clean-up code here */
    return
}
std::string lin;
while(f1))
{
   std::getline(f1,lin); //il terminatore é \n per default.
   vs.push_back(lin);
}
quel che ho fatto è spostare sopra la gestione degli errori lasciandola separata dal ciclo di lettura. la condizione
invariante del while è stata rafforzata. Grazie all'operator bool degli stream sappiamo se sarà possibile fare la
prossima lettura evitando così ogni altra sorta di errore (lo stream non va solo in eof, ma anche in fail e bad).
Evitiamo di chiamare close che sarà comunque chiamata dal costruttore all'uscita dello scope.
Ciao,
--
----------------------------------------------
Fulvio Esposito
WWW: 
http://digilander.iol.it/fesposito
E-Mail Contact me at: 
ful...@libero.it
----------------------------------------------

 all'uscita dello scope.
In realta' e' discutibile anche questo. close() puo' fallire, ed in
questo caso imposta gli opportuni flag dello stream. Se fallisce
presumibilmente e' fallito l'ultimo flush del buffer e presumibilmente
e' il caso di notificare chi di dovere.
Ciao,
Nicola

Beh, leggi una volta di troppo.
E' vero, ma ti sei dimenticato di dire che la cosa avviene solamente
se l'ultima riga ha il terminatore incluso. In questo caso il flag eof
non viene settato e si legge una riga in più che poi risulterà vuota.


 non viene settato e si legge una riga in più che poi risulterà vuota.
Grazie; mi confermi che leggi una volta di troppo.  E non ti sembra
sbagliato?  Inoltre (cito a memoria) a norma di standard C (e quindi
probabilmente anche C++) ogni linea _deve_ contenere un newline.


Evitiamo di chiamare close che sarà comunque chiamata dal costruttore all'uscita dello scope.
Direi che invece close() vada sempre chiamato esplicitamente, non solo
per una questione di estetica, ma anche perché la chiusura potrebbe
fallire ed in tal caso sarebbe oppurtuno fare dei controlli sui flags.
