Convert C++Builder AnsiString to std::string via boost::lexical_cast
- by David Klein
For a school assignment I have to implement a project in C++ using Borland C++ Builder.
As the VCL uses AnsiString for all GUI Components I have to convert all of my std::strings to AnsiString for the sake of displaying.
std::string inp = "Hello world!";
AnsiString outp(inp.c_str());
works of course but is a bit tedious to write and code duplication I want to avoid. As we use Boost in other contexts I decided to provide some helper functions go get boost::lexical_cast to work with AnsiString. Here is my implementation so far:
std::istream& operator>>(std::istream& istr, AnsiString& str) {
istr.exceptions(std::ios::badbit | std::ios::failbit | std::ios::eofbit);
std::string s;
std::getline(istr,s);
str = AnsiString(s.c_str());
return istr;
}
In the beginning I got Access Violation after Access Violation but since I added the .exceptions() stuff the picture gets clearer.
When the conversion is performed I get the following Exception:
ios_base::eofbit set [Runtime Error/std::ios_base::failure]
Does anyone have an idea how to fix it and can explain why the error occurs? My C++ experience is very limited.
The conversion routine the other way round would be:
std::ostream& operator<<(std::ostream& ostr,const AnsiString& str) {
ostr << (str.c_str());
return ostr;
}
Maybe someone will spot an error here too :)
With best regards!
Edit:
At the moment I'm using the edited version of Jem, it works in the beginning. After a while of using the programm the Borland Codeguard mentions some pointer arithmetic in already freed regions. Any ideas how this could be related?
The Codeguard log (I'm using the german version, translations marked with stars):
------------------------------------------
Fehler 00080. 0x104230 (r) (Thread 0x07A4):
Zeigerarithmetik in freigegebenem Speicher: 0x0241A238-0x0241A258. **(pointer arithmetic in freed region)**
| d:\program files\borland\bds\4.0\include\dinkumware\sstream Zeile 126:
| { // not first growth, adjust pointers
| _Seekhigh = _Seekhigh - _Mysb::eback() + _Ptr;
|> _Mysb::setp(_Mysb::pbase() - _Mysb::eback() + _Ptr,
| _Mysb::pptr() - _Mysb::eback() + _Ptr, _Ptr + _Newsize);
| if (_Mystate & _Noread)
Aufrufhierarchie: **(stack-trace)**
0x00411731(=FOSChampion.exe:0x01:010731) d:\program files\borland\bds\4.0\include\dinkumware\sstream#126
0x00411183(=FOSChampion.exe:0x01:010183) d:\program files\borland\bds\4.0\include\dinkumware\streambuf#465
0x0040933D(=FOSChampion.exe:0x01:00833D) d:\program files\borland\bds\4.0\include\dinkumware\streambuf#151
0x00405988(=FOSChampion.exe:0x01:004988) d:\program files\borland\bds\4.0\include\dinkumware\ostream#679
0x00405759(=FOSChampion.exe:0x01:004759) D:\Projekte\Schule\foschamp\src\Server\Ansistringkonverter.h#31
0x004080C9(=FOSChampion.exe:0x01:0070C9) D:\Projekte\Schule\foschamp\lib\boost_1_34_1\boost/lexical_cast.hpp#151
Objekt (0x0241A238) [Größe: 32 Byte] war erstellt mit new **(Object was created with new)**
| d:\program files\borland\bds\4.0\include\dinkumware\xmemory Zeile 28:
| _Ty _FARQ *_Allocate(_SIZT _Count, _Ty _FARQ *)
| { // allocate storage for _Count elements of type _Ty
|> return ((_Ty _FARQ *)::operator new(_Count * sizeof (_Ty)));
| }
|
Aufrufhierarchie: **(stack-trace)**
0x0040ED90(=FOSChampion.exe:0x01:00DD90) d:\program files\borland\bds\4.0\include\dinkumware\xmemory#28
0x0040E194(=FOSChampion.exe:0x01:00D194) d:\program files\borland\bds\4.0\include\dinkumware\xmemory#143
0x004115CF(=FOSChampion.exe:0x01:0105CF) d:\program files\borland\bds\4.0\include\dinkumware\sstream#105
0x00411183(=FOSChampion.exe:0x01:010183) d:\program files\borland\bds\4.0\include\dinkumware\streambuf#465
0x0040933D(=FOSChampion.exe:0x01:00833D) d:\program files\borland\bds\4.0\include\dinkumware\streambuf#151
0x00405988(=FOSChampion.exe:0x01:004988) d:\program files\borland\bds\4.0\include\dinkumware\ostream#679
Objekt (0x0241A238) war Gelöscht mit delete **(Object was deleted with delete)**
| d:\program files\borland\bds\4.0\include\dinkumware\xmemory Zeile 138:
| void deallocate(pointer _Ptr, size_type)
| { // deallocate object at _Ptr, ignore size
|> ::operator delete(_Ptr);
| }
|
Aufrufhierarchie: **(stack-trace)**
0x004044C6(=FOSChampion.exe:0x01:0034C6) d:\program files\borland\bds\4.0\include\dinkumware\xmemory#138
0x00411628(=FOSChampion.exe:0x01:010628) d:\program files\borland\bds\4.0\include\dinkumware\sstream#111
0x00411183(=FOSChampion.exe:0x01:010183) d:\program files\borland\bds\4.0\include\dinkumware\streambuf#465
0x0040933D(=FOSChampion.exe:0x01:00833D) d:\program files\borland\bds\4.0\include\dinkumware\streambuf#151
0x00405988(=FOSChampion.exe:0x01:004988) d:\program files\borland\bds\4.0\include\dinkumware\ostream#679
0x00405759(=FOSChampion.exe:0x01:004759) D:\Projekte\Schule\foschamp\src\Server\Ansistringkonverter.h#31
------------------------------------------
Ansistringkonverter.h is the file with the posted operators and line 31 is:
std::ostream& operator<<(std::ostream& ostr,const AnsiString& str) {
ostr << (str.c_str()); **(31)**
return ostr;
}
Thanks for your help :)