转换为C++;生成器通过boost::lexical\u cast转换到std::string 对于一个学校作业,我必须用Borland C++ Builder实现一个C++项目。

转换为C++;生成器通过boost::lexical\u cast转换到std::string 对于一个学校作业,我必须用Borland C++ Builder实现一个C++项目。,c++,boost,c++builder,lexical-cast,C++,Boost,C++builder,Lexical Cast,由于VCL对所有GUI组件使用AnsiString,为了显示,我必须将所有std::字符串转换为AnsiString std::string inp = "Hello world!"; AnsiString outp(inp.c_str()); 当然可以,但编写起来有点乏味,我希望避免代码重复。当我们在其他上下文中使用Boost时,我决定提供一些帮助函数get Boost::lexical_cast来处理AnsiString。以下是我迄今为止的实施情况: std::istream& o

由于VCL对所有GUI组件使用AnsiString,为了显示,我必须将所有std::字符串转换为AnsiString

std::string inp = "Hello world!";
AnsiString outp(inp.c_str());
当然可以,但编写起来有点乏味,我希望避免代码重复。当我们在其他上下文中使用Boost时,我决定提供一些帮助函数get 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;
}
Ansistringkonverter.h是包含已发布运算符的文件,第31行是:

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

std::ostream&operator您的转换转换一行输入。如果有两行代码,这是一个严重的问题,如果没有,这是一个相当致命的错误。在这种情况下,最好的解决方案不是一个新的
操作符>>
,而是一个模板专门化。我的头顶:

template< > AnsiString lexical_cast<AnsiString, std::string>(std::string const& s)
{
    return AnsiString(s.c_str());
}
template<>AnsiString词法转换(std::string const&s)
{
返回AnsiString(s.c_str());
}

(你不应该让其他人的模板过载。在std::,这是非法的,在其他地方只是不好的做法)

仍然没有使用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::istream&operator>>(std::istream&istr、AnsiString&str)
{ 
std::字符串tmp;
std::istreambuf_迭代器it(istr),结束;
std::copy(it,end,std::inserter(tmp,tmp.begin());
str=AnsiString(tmp.c_str());
返回istr;
} 

然而,对于std::string和AnsiString,使用不同的操作符>>行为可能可以满足您的需要,但总体来说不是很好。您仍然可以给它一个明确的名称。

除了MSalters注释外,将std::字符串的实际长度传递给AnsiString也会更有效,这样就不需要浪费CPU周期来手动计算长度:

template<> System::AnsiString lexical_cast<System::AnsiString, std::string>(std::string const& s)
{
    return System::AnsiString(s.c_str(), s.length());
}
template System::AnsiString词法转换(std::string const&s)
{
返回系统::AnsiString(s.c_str(),s.length());
}

您也可以试试这个!我在使用hashlib++时也遇到过类似的问题

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

可能是输入错误,但不要忘记&in std::ostream&运算符,因为当我忽略.exceptions()调用时,会忽略该错误。因此,当我直接处理结果而不进行处理时,会导致访问冲突。到目前为止,这至少是我的解释。在我看来,“freedregion”的问题并不是由您使用流和字符串引起的,更可能是由您创建/删除它们的方式引起的。您是否在某处使用“新建/删除”?如果您发布了重现问题的最小代码,那么应该不太难发现它。通过非常量引用传递
AnsiString
似乎会导致奇怪的、难以重现的崩溃。他们使用写时复制语义,可能是编译器弄乱了相关的东西。我认为这只会复制一个单词是的,但这可能是预期的行为(或不是)。读取整个缓冲区可以在较高的级别上完成。我记不清streams,但这里甚至可以通过使用stream.get()来避免临时字符串,因为我想读取整个字符串,所以不久前我从>>切换到了getline()。因此,读取整个字符串就是我想要的:)如果我放入istr.exceptions(std::ios::badbit | std::ios::failbit | std::ios::eofbit);调用您编辑的建议,它会与“ios_base::failbit set”崩溃,奇怪:)我认为这是正常的。当您读取流中的所有内容时,根据定义,您将到达流的末尾,并引发异常。如果您没有捕获它(使用try/catch),它会导致您正在经历的崩溃(未处理的异常错误?)。在我的示例中,您不应该设置异常位,也不应该捕获异常,而应该只报告那些实际上是错误的异常。@James:当然,您可以专门化模板函数,只对它们进行部分专门化是不可能的。
String toAnsiString(const std::string& myString)
{
  return String(myString.c_str());
}