簡體   English   中英

通過boost :: lexical_cast將C ++ Builder AnsiString轉換為std :: string

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

對於學校作業,我必須使用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;
}

謝謝你的幫助 :)

仍未使用boost,但可能是解決當前問題的第一步。 您可以嘗試以下方法:

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

編輯:更完整的解決方案,考慮到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; 
} 

但是,對於std :: string和AnsiString具有不同的運算符>>行為也許可以滿足您的需求,但通常情況下不太好。 您仍然可以為其指定一個明確的名稱。

您也可以嘗試一下! 使用hashlib ++時,我也遇到了此類問題。

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

您的轉換將轉換輸入的一行。 如果有兩行,那將是一個嚴重的問題;如果沒有兩行,那將是一個致命的錯誤。 在這種情況下,最好的解決方案不是new operator>> ,而是模板專門化。 我的頭頂:

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

(您不應該超載其他人的模板。在std ::中,這是非法的,在其他地方只是不好的做法)

除了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