2

学校の課題で、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;
}

最初は Access Violation の後に Access Violation を取得しましたが、 .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;
}

ご協力いただきありがとうございます :)

4

4 に答える 4

2

まだブーストを使用していませんが、現在の問題を解決するための最初のステップになる可能性があります。これを試すことができます:

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 で異なる operator >> の動作を使用することは、おそらくニーズには問題ありませんが、一般的にはあまり良くありません。明示的な名前を付けることができます。

于 2009-05-22T14:51:48.147 に答える
1

これも試してみてください!hashlib ++での作業にもそのような問題がありました。

String toAnsiString(const std::string& myString)
{
  return String(myString.c_str());
}
于 2013-03-15T10:55:09.260 に答える
1

変換により、入力の 1 行が変換されます。2 行あると深刻な問題になり、2 行ない場合はかなり致命的なバグになります。この場合の最善の解決策は、 newoperator>>ではなく、テンプレートの特殊化です。私の頭のてっぺん:

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

(他の人のテンプレートをオーバーロードすることは想定されていません。std:: では違法であり、他の場所では悪い習慣です)

于 2009-05-22T14:48:53.767 に答える
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());
}
于 2009-06-01T20:16:21.813 に答える