从 std::string 和 std::wstring 获取 char 整数值

Posted

技术标签:

【中文标题】从 std::string 和 std::wstring 获取 char 整数值【英文标题】:Getting the char integer value from a std::string & std::wstring 【发布时间】:2011-10-20 09:16:43 【问题描述】:

我试图通过在 C++ WinAPI 中将每个字母的 int 值相加来将字符串转换为数字。所以在ASCII中; std::string "AA" 等于 130 (65+65)

字符串可以是 std::string 或 std::wstring。

为什么无论我输入什么字母,下面的函数总是返回零值?它不应该返回字母的 ASCII 或 Unicode 整数值吗?

printf("TEST a: %d \n", _tstoi(_T("a")));
printf("TEST A: %d \n", _tstoi(_T("A")));
printf("TEST b: %d \n", _tstoi(_T("b")));

我的 VC++ 应用程序当前使用 Unicode,并且前面的代码为每个字母打印出零。我记得听说 Unicode 与 ASCII 字符串非常不同,你能弄清楚除了 Unicode 有一个大约 30,000 长而 ASCII 是 256 长的字符库(我认为?)之外还有什么不同吗?

【问题讨论】:

Joel 的“每个软件开发人员绝对、肯定必须了解 Unicode 和字符集的绝对最低要求(没有任何借口!)”joelonsoftware.com/articles/Unicode.html 【参考方案1】:

msdn 文章说:

"输入的字符串是一个可以被解释的字符序列 作为指定类型的数值。函数停止读取 无法识别的第一个字符处的输入字符串 数字的一部分。”

如果您使用包含实际数字的 unicode 字符串测试代码,您将看到正确的输出:

printf("TEST 1: %d \n", _tstoi(_T("1")));

输出:

TEST 1: 1

就像@Ylisar 所说,*toi 函数用于将数字值从字符串转换为整数变量。

以下代码将改为输出数字表示,但要注意 const 变量的指针表示。我已经留下了两个版本,所以你可以看到区别:

  printf("TEST 1: %d \n", _tstoi(_T("1")));
  printf("TEST a: %d \n", _tstoi(_T("a")));
  WCHAR* b(_T("b"));
  printf("TEST A: %d \n", _T("A"));
  printf("TEST b: %d \n", *b);

输出:

TEST 1: 1
TEST a: 0
TEST A: 13457492
TEST b: 98

在http://msdn.microsoft.com/en-us/library/yd5xkb5c%28v=vs.80%29.aspx查看更多信息

如果你想总结(累加)这些值,我建议你查看 STL 范围函数,它对这些事情有奇效。例如

#include <numeric>
#include <string>

printf("TEST a: %d \n", *_T("a")); // 97
printf("TEST b: %d \n", *_T("b")); // 98

wstring uString(_T("ba"));
int result = accumulate(uString.begin(), uString.end(), 0);
printf("TEST accumulated: %d \n", result);

结果:

TEST a: 97
TEST b: 98
TEST accumulated: 195

这样您就不必让 for 循环遍历所有值。范围函数真的很适合这样的东西。

查看更多信息:http://www.sgi.com/tech/stl/accumulate.html

【讨论】:

【参考方案2】:

*toi 系列函数将字符串表示形式转换为整数表示形式,即“10”变为 10。您真正想要做的根本不是转换。将其更改为:

printf("TEST a: %d \n", _T('a')); printf("测试 A: %d \n", _T('A')); printf("测试 b: %d \n", _T('b'));

对于 unicode,底层表示取决于编码(例如非常流行的 UTF-8,将 LSB 与 ASCII 表映射)。

【讨论】:

那么这样做是否可以得到字符串的总和... int x += (int)_T("a"); ?或者也许我应该做长转换或无符号整数转换?或者甚至是静态演员表? 所有 char 类型都只是无符号整数类型,除了可能使用 static_cast 来抑制可能与位宽差异相关的编译器警告之外,不需要进行任何转换。无符号整数 x = _T('a');例如应该没问题。 _T("a") 包含一个 NULL 终止符,实际上是一个长度为 2 的数组。【参考方案3】:

Ylisar 已经回答了第一个问题,为什么 printf 不能按预期工作。关于对字符的十六进制表示求和的另一个问题要复杂一些。使用 _tstoi() 函数从字符串到数值的转换只有在给定的字符串表示像“123”这样的数字转换为 123 时才有效。您想要的是字符表示的总和。

如果 Unicode 代码点低于 0x7F (0...127),这只是 1 字节 UTF-8 表示的总和。但是,在使用 UNICODE 标志编译的 Windows 上,使用每个字符 2 字节的表示。在调试器中运行以下代码将实现这一点。

// ASCII 1 Byte per character
const char* letterA = "A";
int sumOfLetterA = letterA[0] + letterA[0]; // gives 130

// 2 Bytes per character (Windows)
const wchar_t* letterB = TEXT("B");
int sumOfLetterB = letterB[0] + letterB[0]; // gives 132

【讨论】:

Windows always 使用 2 字节 Unicode 表示 WCHARalways 使用 1 字节 ASCII+ 编码表示 charUNICODE 宏改变了TCHAR typedef 和一堆函数宏。 是的,我知道,我不够精确,但正如我提到的“使用 UNICODE 标志编译”并且假设字符串是使用宏 L() 或 T() 窗口字符之一生成的2 个字节长。

以上是关于从 std::string 和 std::wstring 获取 char 整数值的主要内容,如果未能解决你的问题,请参考以下文章

无法从 'const std::string [3]' 转换为 'std::string'

从 std::string 解析整数,但如果是浮点数则失败

如何摆脱“Intellisense:没有合适的转换函数从“std::string”到“std::string *”存在”错误?

Cython C++ 和 std::string

从 Go 中迭代`std::vector<std::string>`?

从输入迭代器创建 C++ std::string 的性能