Dong Zhou <nosarthur@yahoo.com.cn> wrote concerning
[ROOT] iostream [Mon, 29 Sep 2003 20:04:17 +0800 (CST)]
----------------------------------------------------------------------
> dear rooters:
>
> i feel there is something wrong with the 'fin >>' method.
Nothing wrong.
> it should be 0 0.1 0.2
> but the output turns out to be 0.1 0.2 0.2
> it seems that it take 00.1 as 0.1
Look in `tmp.dat' - what you see is
> cat tmp.dat
00.10.2
So the first `std::ostream& operator>>(ostream&,double&)' will read
`00.10' - that is, as much as possible consistent with a number. The
next read will read `.2', and the third will actually fail.
Try inserting the line
for(int i=0;i<3;++i){
fin >> arr;
if (fin.fail()) cout << "bad read: " << flush; // Added
cout << i << ' ' << arr << endl;
}
and you'll see it.
> i am not sure if i have made any mistake. what is ur opinion?
You did. What you need to do, is to put some white space (which is
ignored per default by all `template <typename T> std::ostream
operator>>(std::ostream&, T&)'), after you output the number in the
first loop. Also, it's always a good idea to check if your read was
successful, and if not fail. See the (pure C++) code below:
#ifndef __IOSTREAM__
#include <iostream>
#endif
#ifndef __FSTREAM__
#include <fstream>
#endif
#ifndef __VECTOR__
#include <vector>
#endif
#ifndef __STDEXCEPT__
#include <stdexcept>
#endif
int main()
{
try {
std::vector<double> fixed(3);
fixed[0] = 0;
fixed[1] = 0.1;
fixed[2] = 0.2;
std::ofstream out("tmp.dat");
for (std::vector<double>::const_iterator i = fixed.begin();
i != fixed.end(); ++i)
out << (*i) << "\t";
out << std::endl;
out.close();
std::ifstream in("tmp.dat");
std::vector<double> read;
while (!in.eof()) {
double tmp;
in >> tmp;
if (in.eof()) break;
if (in.fail()) throw std::runtime_error("failed during read");
read.push_back(tmp);
}
if (fixed.size() != read.size())
throw std::runtime_error("short read");
for (std::vector<double>::const_iterator i = fixed.begin(),
j = read.begin(); i != fixed.end() && j != read.end();
++i, ++j) {
std::cout << "output: " << *i << "\tinput: " << *j << std::endl;
if (*j != *i)
throw std::runtime_error("input and output differ");
}
}
catch(std::exception& e) {
std::cerr << e.what() << std::endl;
return 1;
}
return 0;
}
The thing to remember is that the `put-to' and `get-from' operators do
_formatted_ Input/Output, and not binary I/O. To do binary I/O, you
should use the `get' and `put' member functions of `template <typename
CharT> class basic_iostream' (and similar) or the C FILE interface.
Read the GNU LibStdC++ manual on this - it explains these issues in
details. I don't think M$DN comments on this, as must of the
documentation is ripped from the ISO/IEC C++ Standard, which is
remarkably quite on these (and other) issues, but I may be wrong.
Yours,
___ | Christian Holm Christensen
|_| | -------------------------------------------------------------
| | Address: Sankt Hansgade 23, 1. th. Phone: (+45) 35 35 96 91
_| DK-2200 Copenhagen N Cell: (+45) 24 61 85 91
_| Denmark Office: (+45) 353 25 404
____| Email: cholm@nbi.dk Web: www.nbi.dk/~cholm
| |
This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:15 MET