对于学校作业,我必须使用Borland C ++ Builder在C ++中实现一个项目。
由于VCL对所有GUI组件使用AnsiString,我必须将所有std :: strings转换为AnsiString以便显示。
std::string inp = "Hello world!";
AnsiString outp(inp.c_str());
当然是有效的,但是我想要避免编写和编码重复有点单调乏味。当我们在其他上下文中使用Boost时,我决定提供一些辅助函数来获取boost :: lexical_cast以使用AnsiString。这是我到目前为止的实现:
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;
}
一开始我在访问冲突后获得了访问冲突,但由于我添加了.exceptions()内容,因此图片变得更加清晰。 执行转换时,我得到以下异常:
ios_base::eofbit set [Runtime Error/std::ios_base::failure]
有没有人知道如何修复它并可以解释错误发生的原因?我的C ++经验非常有限。
反过来的转换例程是:
std::ostream& operator<<(std::ostream& ostr,const AnsiString& str) {
ostr << (str.c_str());
return ostr;
}
也许有人会在这里发现错误:)
最诚挚的问候!
编辑:
目前我正在使用Jem的编辑版本,它在一开始就有效。使用该程序一段时间后,Borland Codeguard在已经释放的区域中提到了一些指针算法。任何想法如何相关?
Codeguard日志(我使用的是德语版本,标有星号的翻译):
------------------------------------------
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是包含已发布运算符的文件,第31行是:
std::ostream& operator<<(std::ostream& ostr,const AnsiString& str) {
ostr << (str.c_str()); **(31)**
return ostr;
}
感谢您的帮助:)
答案 0 :(得分:1)
仍然没有使用提升,但可能是解决当前问题的第一步。你可以试试这个:
std::istream& operator>>(std::istream& istr, AnsiString& str) {
istr.exceptions(std::ios::badbit | std::ios::failbit | std::ios::eofbit);
std::string s;
istr >> s;
str = AnsiString(s.c_str());
return istr;
}
编辑:更完整的解决方案,考虑到操作的评论:
std::istream& operator>> (std::istream& istr, AnsiString& str)
{
std::string tmp;
std::istreambuf_iterator<char> it(istr), end;
std::copy(it, end, std::inserter(tmp, tmp.begin()));
str = AnsiString(tmp.c_str());
return istr;
}
然而,具有不同的运算符&gt;&gt; std :: string和AnsiString的行为可能已经满足您的需求,但一般来说不是很好。你仍然可以给它一个明确的名字。
答案 1 :(得分:0)
您的转化会转换输入的一行。如果有两行,这是一个严重的问题,如果没有,那就是一个相当致命的错误。在这种情况下,最佳解决方案不是新的operator>>
,而是模板专业化。我的头脑:
template< > AnsiString lexical_cast<AnsiString, std::string>(std::string const& s)
{
return AnsiString(s.c_str());
}
(你不应该重载其他人的模板。在std ::中,这是非法的,其他地方只是不好的做法)
答案 2 :(得分:0)
除了MSalters注释之外,将std :: string的实际长度传递给AnsiString会更有效率,因此不需要浪费CPU周期来手动计算长度:
template<> System::AnsiString lexical_cast<System::AnsiString, std::string>(std::string const& s)
{
return System::AnsiString(s.c_str(), s.length());
}
答案 3 :(得分:0)
您也可以试试这个!我也遇到了使用hashlib ++的那种问题。
String toAnsiString(const std::string& myString)
{
return String(myString.c_str());
}