简体   繁体   English

通过boost :: lexical_cast将C ++ Builder AnsiString转换为std :: string

[英]Convert C++Builder AnsiString to std::string via boost::lexical_cast

For a school assignment I have to implement a project in C++ using Borland C++ Builder. 对于学校作业,我必须使用Borland C ++ Builder在C ++中实现一个项目。

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. 由于VCL对所有GUI组件都使用AnsiString,因此为了显示,我必须将所有std :: strings都转换为AnsiString。

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. 当我们在其他上下文中使用Boost时,我决定提供一些帮助器函数以使boost :: lexical_cast与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. 一开始我在访问冲突之后遇到了访问冲突,但是由于我添加了.exceptions()东西,因此画面变得更加清晰。 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. 我的C ++经验非常有限。

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. 目前,我正在使用Jem的编辑版本,它从一开始就可以使用。 After a while of using the programm the Borland Codeguard mentions some pointer arithmetic in already freed regions. 在使用该程序一段时间后,Borland Codeguard在已经释放的区域中提到了一些指针算法。 Any ideas how this could be related? 有什么想法可以联系起来吗?

The Codeguard log (I'm using the german version, translations marked with stars): 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 is the file with the posted operators and line 31 is: Ansistringkonverter.h是带有发布的运算符的文件,第31行是:

std::ostream& operator<<(std::ostream& ostr,const AnsiString& str) {
    ostr << (str.c_str()); **(31)**
    return ostr;
}

Thanks for your help :) 谢谢你的帮助 :)

Still not using boost, but may be a first step to solve your current problem. 仍未使用boost,但可能是解决当前问题的第一步。 You may try this: 您可以尝试以下方法:

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;
}

EDIT: more complete solution, taking op's comments into account: 编辑:更完整的解决方案,考虑到op的评论:

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; 
} 

However, having different operator >> behavior for std::string and AnsiString is probably ok for your needs, but not very nice in general. 但是,对于std :: string和AnsiString具有不同的运算符>>行为也许可以满足您的需求,但通常情况下不太好。 You can still give it an explicit name. 您仍然可以为其指定一个明确的名称。

You may also try this! 您也可以尝试一下! I had also that kind of problem working with hashlib++. 使用hashlib ++时,我也遇到了此类问题。

String toAnsiString(const std::string& myString)
{
  return String(myString.c_str());
}

Your conversion converts one line of the input. 您的转换将转换输入的一行。 That's a serious problem if there are two lines, and a rather fatal bug if there are none. 如果有两行,那将是一个严重的问题;如果没有两行,那将是一个致命的错误。 The best solution in this case is not a new operator>> , but a template specialization. 在这种情况下,最好的解决方案不是new operator>> ,而是模板专门化。 Top of my head: 我的头顶:

template< > AnsiString lexical_cast<AnsiString, std::string>(std::string const& s)
{
    return AnsiString(s.c_str());
}

(You're not supposed to overload other peoples templates. In std::, it's illegal, elsewhere just bad practice) (您不应该超载其他人的模板。在std ::中,这是非法的,在其他地方只是不好的做法)

In addition to MSalters comments, It would be more efficient to pass the std::string's actual length to AnsiString as well, so that it does not need waste CPU cycles to calculating the length manually: 除了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());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM