[BGL] Encountering "bad lexical cast" exception when reading a class from graphviz file
Hi all,
I am trying to read a graphviz file into my graph implementation. The
minimum working code as well as the graphviz file are at the end of
this e-mail. The node of the graph is the Vertex struct, which
contains a point object (Point p). For Point class, I overload two
operators, >> and <<, and operator << was previously used to generate
the graphviz file. The operator overloads work well with std::cin and
std::cout, but with the code below, I receive an exception:
bad lexical cast: source type value could not be interpreted as target .
The culprit might be in the << overload. In particular, when reading
from a file, the value of iToBool1 is true, whereas iToBool2 is false.
That is to say, the variable i might change when inserting the stream
data to the point. This does not happen when reading from std::cin, as
both variables are true.
I convert the i variable, originally an istream, to bool because when
the program returns to the calling function, which is
lexical_stream_limited_src::shr_using_base_class on line 1616 in
lexical_cast.hpp, this functions uses the return value of << operator
in a boolean comparison. The value of iToBool2 being false eventually
leads to calling BOOST_LCAST_THROW_BAD_CAST on line 1975.
I wonder if somebody can tell me what is wrong with my operator overload?
I use Boost 1.50 and Visual Studio 2008 on Windows 7.
Thanks!
Best regards,
Nicholas
//--------------------Graphviz--------------------
graph G {
1 [Point="1 2 3"];
}
//----------------------code----------------------
#include
On Sat, 21 Jul 2012, Nicholas Mario Wardhana wrote:
Hi all,
I am trying to read a graphviz file into my graph implementation. The minimum working code as well as the graphviz file are at the end of this e-mail. The node of the graph is the Vertex struct, which contains a point object (Point p). For Point class, I overload two operators, >> and <<, and operator << was previously used to generate the graphviz file. The operator overloads work well with std::cin and std::cout, but with the code below, I receive an exception:
bad lexical cast: source type value could not be interpreted as target .
The culprit might be in the << overload. In particular, when reading from a file, the value of iToBool1 is true, whereas iToBool2 is false. That is to say, the variable i might change when inserting the stream data to the point. This does not happen when reading from std::cin, as both variables are true.
I convert the i variable, originally an istream, to bool because when the program returns to the calling function, which is lexical_stream_limited_src::shr_using_base_class on line 1616 in lexical_cast.hpp, this functions uses the return value of << operator in a boolean comparison. The value of iToBool2 being false eventually leads to calling BOOST_LCAST_THROW_BAD_CAST on line 1975.
I wonder if somebody can tell me what is wrong with my operator overload?
I use Boost 1.50 and Visual Studio 2008 on Windows 7.
Can you do lexical_cast<Point>("1 2 3")? If that fails, make sure that reading that string as a Point using istringstream reads the entire contents of the stream (hits EOF and does not set failbit); I am not good enough with streams to know exactly why your code is failing beyond that. If the lexical_cast succeeds, there is a bug in BGL's parsing of the string and I'll take a look at it further. -- Jeremiah Willcock
On 22 July 2012 02:43, Jeremiah Willcock
Can you do lexical_cast<Point>("1 2 3")? If that fails, make sure that reading that string as a Point using istringstream reads the entire contents of the stream (hits EOF and does not set failbit); I am not good enough with streams to know exactly why your code is failing beyond that. If the lexical_cast succeeds, there is a bug in BGL's parsing of the string and I'll take a look at it further.
-- Jeremiah Willcock _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks for your reply, Jeremiah! I tried lexical_cast<Point>("1 2 3") and it fails with the same exception too. As for the istringstream part, my code is std::istringstream iStringStream("1"); Point p2; std::istream& returnValue = iStringStream >> p2; std::cout << "Does it reach EOF? " << (returnValue.eof()? "yes" : "no") << std::endl; std::cout << "Is it bad? " << (returnValue.bad()? "yes" : "no") << std::endl; std::cout << "Does it fail? " << (returnValue.fail()? "yes" : "no") << std::endl; std::cout << "Is it good? " << (returnValue.good()? "yes" : "no") << std::endl; This is what it prints. Does it reach EOF? yes Is it bad? no Does it fail? yes Is it good? no So, I suppose the stream reaches EOF, and it is not bad, but it fails, and therefore it is not good. I wonder that these mean? I think I'll search more about that... Thanks again. Best regards, Nicholas
On 22 July 2012 03:24, Nicholas Mario Wardhana
Thanks for your reply, Jeremiah!
I tried lexical_cast<Point>("1 2 3") and it fails with the same exception too.
As for the istringstream part, my code is
std::istringstream iStringStream("1"); Point p2; std::istream& returnValue = iStringStream >> p2; std::cout << "Does it reach EOF? " << (returnValue.eof()? "yes" : "no") << std::endl; std::cout << "Is it bad? " << (returnValue.bad()? "yes" : "no") << std::endl; std::cout << "Does it fail? " << (returnValue.fail()? "yes" : "no") << std::endl; std::cout << "Is it good? " << (returnValue.good()? "yes" : "no") << std::endl;
This is what it prints.
Does it reach EOF? yes Is it bad? no Does it fail? yes Is it good? no
So, I suppose the stream reaches EOF, and it is not bad, but it fails, and therefore it is not good. I wonder that these mean? I think I'll search more about that...
Thanks again.
Best regards, Nicholas
Oops, I made a mistake. I just input "1" in my previous e-mail, so I
changed it to "1 2 3", and this is what I get:
Does it reach EOF? yes
Is it bad? no
Does it fail? no
Is it good? no
So it reaches EOF, and it is not good.
The updated code and the output are at the end of this e-mail. It
seems like the graphviz and lexical_cast cases suffer from setting the
failbit, whereas the istringstream case sets the eofbit. No flag is
set in the std::cin case.
Thanks!
Best regards,
Nicholas
//------------------------code------------------------
#include
On 22 July 2012 04:09, Nicholas Mario Wardhana
Oops, I made a mistake. I just input "1" in my previous e-mail, so I changed it to "1 2 3", and this is what I get:
Does it reach EOF? yes Is it bad? no Does it fail? no Is it good? no
So it reaches EOF, and it is not good.
The updated code and the output are at the end of this e-mail. It seems like the graphviz and lexical_cast cases suffer from setting the failbit, whereas the istringstream case sets the eofbit. No flag is set in the std::cin case.
Thanks!
Best regards, Nicholas
I finally solved this problem. The correct, at least better, way to save/read the data is like mentioned in http://stackoverflow.com/questions/10382884/c-using-classes-with-boostlexica... , which in my case becomes //==================================== inline friend std::ostream& operator << ( std::ostream& o, const Vec3& v ) { o << v.x << " " << v.y << " " << v.z; return o; } inline friend std::istream& operator >> ( std::istream& i, Vec3& v ) { i >> v.x; if((i.flags() & std::ios_base::skipws) == 0) { char whitespace; i >> whitespace; } i >> v.y; if((i.flags() & std::ios_base::skipws) == 0) { char whitespace; i >> whitespace; } i >> v.z; return i; } //==================================== This has also apparently been a topic of discussion for quite some time. http://lists.boost.org/Archives/boost/2005/01/79275.php Thank you again! Best regards, Nicholas
participants (2)
-
Jeremiah Willcock
-
Nicholas Mario Wardhana