转换(const char *)var出错了

问题描述 投票:1回答:3

我需要在嵌入式Visual C ++中将CString转换为double,它只支持旧式C ++。我使用以下代码

CString str = "4.5"; double var = atof( (const char*) (LPCTSTR) str )

结果是var=4.0,所以我丢失十进制数字。我做了另一个测试

LPCTSTR str = "4.5"; const char* var = (const char*) str

再次结果var=4.0任何人都可以帮助我得到正确的结果吗?

c++ mfc char double c-strings
3个回答
1
投票

这里的问题是,你对编译器撒谎,编译器信任你。使用嵌入式Visual C ++我将假设您的目标是Windows CE。 Windows CE仅公开Unicode API表面,因此您的项目很可能设置为使用Unicode(UTF-16 LE编码)。

在这种情况下,CString扩展到CStringW,它将代码单元存储为wchar_t。在做(const char*) (LPCTSTR) str时,你将从wchar_t const*投射到char const*。给定输入,第一个字节的值为52(字符4的ASCII编码)。第二个字节的值为0.这被解释为C样式字符串的终止符。换句话说,你将字符串"4"传递给你对atof的调用。当然,你会得到值4.0作为结果。

要修复代码,请使用以下内容:

CStringW str = L"4.5";
double var = _wtof( str.GetString() );

_wtof是微软特有的CRT扩展。

特别注意两件事:

  • 该代码使用带有显式字符编码的CString变体(CStringW)。始终明确您的字符串类型。这有助于读取代码并在错误发生之前捕获它们(尽管原始代码中的所有C风格的强制转换都完全失败了)。
  • 代码调用CString::GetString成员来检索指向不可变缓冲区的指针。这也使代码更容易阅读,不使用看起来像C风格的演员(而是运算符)。

还要考虑定义_CSTRING_DISABLE_NARROW_WIDE_CONVERSION宏以防止无意的字符集转换发生(例如CString str = "4.5";)。这也有助于你及早发现错误(除非你用C风格的演员表击败它)。


1
投票

CString不是const char*要将TCHAR CString转换为ASCII,请使用CT2A宏 - 这也允许您将字符串转换为UTF8(或任何其他Windows代码页):

// Convert using the local code page
CString str(_T("Hello, world!"));
CT2A ascii(str);
TRACE(_T("ASCII: %S\n"), ascii.m_psz);

// Convert to UTF8
CString str(_T("Some Unicode goodness"));
CT2A ascii(str, CP_UTF8);
TRACE(_T("UTF8: %S\n"), ascii.m_psz);

0
投票

使用scanf找到解决方案

CString str="4.5" double var=0.0; _stscanf( str, _T("%lf"), &var );

这给出了正确的结果var=4.5感谢大家的意见和帮助。

© www.soinside.com 2019 - 2024. All rights reserved.