Newsgroup: it.comp.lang.c++
Titolo: Problema su input stream...

Ciao, avevo bisogno di leggere da un file una serie di numeri in
esadecimale.
Ho scritto una funzione per farlo ma con il debugger ho visto che leggeva
fischi per fiaschi.
Allora pensando di essermi sbagliato ho provato a leggere dei valori da cin
scrivendo un programmino di due righe per vedere cosa accadeva...
Ecco il cuore del programmino che ho scritto.
int offs;
int size;
cin.flags(ios::hex);
cin >> offs;
cin >> size;
cout << "OFFS: " << offs << " SIZE: " << size << endl;
Il mio problema è che se tolgo la terza linea, lancio il programma e scrivo
"10 20" (senza gli apici) ottengo
la risposta corretta, se lascio invece la terza linea, lancio il programma e
scrivo la stessa linea anziché trovarmi la risposta giusta, ovvero 16 e 32,
noto che il primo viene letto correttamente ma il secondo è un numero uguale
al primo...
Cosa c'è che non va?
Ho sbagliato? C'è un modo corretto per fare questo...
Il compilatore è il Borland C++ Builder ma comunque sto cercando di aderire
allo standard (ecco di seguito il programmino che ho utilizzato per testare
la lettura di due numeri esadecimali, se qualcuno sa dov'è l'errore mi
farebbe un piacere, altrimenti dovrò leggere dei caratteri e convertirli io
mediante una mia funzione ma... che palle...).
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
        int offs;
        int size;
        cin.flags(ios::hex);
        cin >> offs;
        cin >> size;
        cout << "OFFS: " << offs << " SIZE: " << size << endl;
        return 0;
}
Grazie a tutti,
Paolo Ferraresi.


...
Prova cosi':
        cin.flags(ios::hex);
        cin >> offs;
        cin.ignore();
        cin >> size;
Maurus


O meglio, grazie a Bruce Eckel dovresti fare cosi':
        //    cin.flags(ios::hex); commenta questa linea
        cin.setf(ios::hex, ios::basefield);
        cin >> offs;
        cin >> size;
La spiegazione del nostro eroe:
"
The second type of formatting flags work in a group. You can have only one
of these flags on at a time, like the buttons on old car radios - you push
one in, the rest pop out. Unfortunately this doesn't happen automatically,
and you have to pay attention to what flags you're setting so you don't
accidentally call the wrong setf( ) function. For example, there's a flag
for each of the number bases: hexadecimal, decimal, and octal. Collectively,
these flags are referred to as the ios::basefield. If the ios::dec flag is
set and you call setf(ios::hex), you'll set the ios::hex flag, but you won't
clear the ios::dec bit, resulting in undefined behavior. The proper thing to
do is call the second form of setf( ) like this: setf(ios::hex,
ios::basefield). This function first clears all the bits in the
ios::basefield, then sets ios::hex. Thus, this form of setf( ) ensures that
the other flags in the group "pop out" whenever you set one. Of course, the
hex( ) manipulator does all this for you, automatically, so you don't have
to concern yourself with the internal details of the implementation of this
class or to even care that it's a set of binary flags. Later you'll see
there are manipulators to provide equivalent functionality in all the places
you would use setf( ).
"
Capitolo 2 del secondo volume di "Thinking in C++"
In effetti comunque l'effetto di mettere cin.ignore() fra le 2 cin risolveva
anche il problema ma non so il perche'!
Maurus

 La spiegazione del nostro eroe:
E' proprio un eroe... Ma come fanno a sapere sempre tutto...
Grazie mi sei stato veramente di grande aiuto... Mi pareva una banalità
invece stava per diventare un incubo.
Ciao.
Paolo.