Itoa 和不同的字符集 c++ visual studio 2013
Itoa and different character sets c++ visual studio 2013
我的代码:
m_ListCtrlCandidates.InsertItem(i, _itoa_s(candidate[i].ID, (char*)(LPCTSTR)str, 10));
m_ListCtrlCandidates.SetItemText(i, 1, _itoa(candidate[i].FingerNumber, (char*)(LPCTSTR)str, 10));
m_ListCtrlCandidates.SetItemText(i, 2, _itoa(candidate[i].SampleNumber, (char*)(LPCTSTR)str, 10));
m_ListCtrlCandidates.SetItemText(i, 3, _itoa(candidate[i].ConfidenceLevel, (char*)(LPCTSTR)str, 10));
错误:
Error 2 error C4996: '_itoa': This function or variable may be unsafe. Consider using _itoa_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. d:\documents\visual studio 2013\projects\gatekeeper\gatekeeper\gatekeeperdlg.cpp 416 1 Gatekeeper
我使用的 SDK 在其示例中包含以下代码。它将潜在的匹配项添加到对话框中的列表中。最初我将我的项目设置为 unicode 并更新了代码以使其工作。这给我带来了麻烦,所以我查看了示例代码,发现它的字符集是空白的。所以我改变了我的,现在我得到了这个错误。
如果我将其切换为 _itoa_s,我会收到该函数不接受 3 个参数的错误。所以我想我错过了大小参数,但我不确定它应该是什么大小。此外,当保留为 _itoa 时,它在示例代码中编译得很好。
我真的很想用 Unicode 保存它。使用 _wtoi 而不是 atoi 在其他地方有所帮助。这个案例有类似的东西吗?
I'm using an SDK that has the following code in their sample.
真不幸!
_itoa(candidate[i].FingerNumber, (char*)(LPCTSTR)str, 10)
我猜你正在使用 MFC,str
是一个 CString
,而你正在调用 CListCtrl::SetItemText
。
CString
上的 (LPCTSTR)
运算符获取指向保存字符串数据的底层缓冲区的指针。那是一个 const TCHAR*
,所以如果你在 ANSI 模式下编译,这是一个指向字节的 const char*
指针;在 Unicode 模式下,它是 const wchar_t*
指向 16 位代码单元的指针。
将其转换为非常量 char*
并要求 _itoa
写入它是一个非常糟糕的主意。这会覆盖 CString
中原来的内容,如果数字足够大,结果字符串比 CString
中原来的字符串长,你可能会写到数组的末尾,导致内存不足腐败浩劫。
在 Unicode 模式下将其转换为 char*
甚至更奇怪,因为您使用 wchar_t
数组作为 char*
字节的存储。而 SetItemText()
在 Unicode 模式下肯定会期望得到 wchar_t
个字符吗?
Using _wtoi instead of atoi helped in other places. Is there something similar
_itow
作为 _itoa
的 wchar_t
类似物存在。 (至少在 VS 中。这两个函数本身都不是标准的 C[++]。)
您可以打开 #ifdef _UNICODE
并调用 _itoa
或 _itow
以匹配 TCHAR
的任何类型。但是,除非您出于某些遗留原因真的需要支持一个古老的纯 ANSI 构建,否则现在没有太多理由为 TCHAR
切换而烦恼。您通常可以坚持使用 Unicode 模式并使用基于 wchar_t
的文本字符串。
error C4996: '_itoa': This function or variable may be unsafe.
Microsoft 弃用了一些将可变数量的内容写入预分配缓冲区的 C 函数,因为缓冲区很容易太短,导致上述内存损坏恐怖。过去,这一直是应用程序中无数安全问题的原因,因此最好避免。
不幸的是,警告 4996 实际上弃用了一些并不真正危险的标准函数,这非常令人厌烦,特别是因为建议作为替代的 _s
版本通常不受其他编译器支持。
在这种情况下,尽管 MS 是正确的,但 _itoa
并不是很安全。要安全地使用它,您必须为您传递的类型的最长可能整数分配一个足够大的缓冲区,而且很容易出错。
If I switch it to _itoa_s I get the error that the function doesn't take 3 arguments. So I guess I'm missing the size argument, but I'm not sure what size it is suppose to be
然而,在要写入的指针末尾有许多元素可用。所以目前这将取决于 CString
的长度,你正在窃取其缓冲区。但这样做不是一个好主意。您可以分配自己的缓冲区:
wchar_t str[8];
_itow_s(candidate[i].FingerNumber, str, 8, 10);
这是安全的,但如果 FingerNumber 超过 7 位数字仍然会失败(错误号 EINVAL
),因为没有 space 来存储它们(包括 [=42= ]
终结者)。
像 itoa
这样的将变量内容写入缓冲区的函数通常非常难看。如果您可以将现代 C++ 与 STL 一起使用,则可以使用更简单、更安全的字符串处理方法,例如:
#include <string>
std::wstring fingers = std::to_wstring(candidate[i].FingerNumber);
m_ListCtrlCandidates.SetItemText(i, 1, fingers.c_str());
(尽管这与老式 MFC 和 CString 的混合程度如何是另一个问题。)
我的代码:
m_ListCtrlCandidates.InsertItem(i, _itoa_s(candidate[i].ID, (char*)(LPCTSTR)str, 10));
m_ListCtrlCandidates.SetItemText(i, 1, _itoa(candidate[i].FingerNumber, (char*)(LPCTSTR)str, 10));
m_ListCtrlCandidates.SetItemText(i, 2, _itoa(candidate[i].SampleNumber, (char*)(LPCTSTR)str, 10));
m_ListCtrlCandidates.SetItemText(i, 3, _itoa(candidate[i].ConfidenceLevel, (char*)(LPCTSTR)str, 10));
错误:
Error 2 error C4996: '_itoa': This function or variable may be unsafe. Consider using _itoa_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. d:\documents\visual studio 2013\projects\gatekeeper\gatekeeper\gatekeeperdlg.cpp 416 1 Gatekeeper
我使用的 SDK 在其示例中包含以下代码。它将潜在的匹配项添加到对话框中的列表中。最初我将我的项目设置为 unicode 并更新了代码以使其工作。这给我带来了麻烦,所以我查看了示例代码,发现它的字符集是空白的。所以我改变了我的,现在我得到了这个错误。
如果我将其切换为 _itoa_s,我会收到该函数不接受 3 个参数的错误。所以我想我错过了大小参数,但我不确定它应该是什么大小。此外,当保留为 _itoa 时,它在示例代码中编译得很好。
我真的很想用 Unicode 保存它。使用 _wtoi 而不是 atoi 在其他地方有所帮助。这个案例有类似的东西吗?
I'm using an SDK that has the following code in their sample.
真不幸!
_itoa(candidate[i].FingerNumber, (char*)(LPCTSTR)str, 10)
我猜你正在使用 MFC,str
是一个 CString
,而你正在调用 CListCtrl::SetItemText
。
CString
上的 (LPCTSTR)
运算符获取指向保存字符串数据的底层缓冲区的指针。那是一个 const TCHAR*
,所以如果你在 ANSI 模式下编译,这是一个指向字节的 const char*
指针;在 Unicode 模式下,它是 const wchar_t*
指向 16 位代码单元的指针。
将其转换为非常量 char*
并要求 _itoa
写入它是一个非常糟糕的主意。这会覆盖 CString
中原来的内容,如果数字足够大,结果字符串比 CString
中原来的字符串长,你可能会写到数组的末尾,导致内存不足腐败浩劫。
在 Unicode 模式下将其转换为 char*
甚至更奇怪,因为您使用 wchar_t
数组作为 char*
字节的存储。而 SetItemText()
在 Unicode 模式下肯定会期望得到 wchar_t
个字符吗?
Using _wtoi instead of atoi helped in other places. Is there something similar
_itow
作为 _itoa
的 wchar_t
类似物存在。 (至少在 VS 中。这两个函数本身都不是标准的 C[++]。)
您可以打开 #ifdef _UNICODE
并调用 _itoa
或 _itow
以匹配 TCHAR
的任何类型。但是,除非您出于某些遗留原因真的需要支持一个古老的纯 ANSI 构建,否则现在没有太多理由为 TCHAR
切换而烦恼。您通常可以坚持使用 Unicode 模式并使用基于 wchar_t
的文本字符串。
error C4996: '_itoa': This function or variable may be unsafe.
Microsoft 弃用了一些将可变数量的内容写入预分配缓冲区的 C 函数,因为缓冲区很容易太短,导致上述内存损坏恐怖。过去,这一直是应用程序中无数安全问题的原因,因此最好避免。
不幸的是,警告 4996 实际上弃用了一些并不真正危险的标准函数,这非常令人厌烦,特别是因为建议作为替代的 _s
版本通常不受其他编译器支持。
在这种情况下,尽管 MS 是正确的,但 _itoa
并不是很安全。要安全地使用它,您必须为您传递的类型的最长可能整数分配一个足够大的缓冲区,而且很容易出错。
If I switch it to _itoa_s I get the error that the function doesn't take 3 arguments. So I guess I'm missing the size argument, but I'm not sure what size it is suppose to be
然而,在要写入的指针末尾有许多元素可用。所以目前这将取决于 CString
的长度,你正在窃取其缓冲区。但这样做不是一个好主意。您可以分配自己的缓冲区:
wchar_t str[8];
_itow_s(candidate[i].FingerNumber, str, 8, 10);
这是安全的,但如果 FingerNumber 超过 7 位数字仍然会失败(错误号 EINVAL
),因为没有 space 来存储它们(包括 [=42= ]
终结者)。
像 itoa
这样的将变量内容写入缓冲区的函数通常非常难看。如果您可以将现代 C++ 与 STL 一起使用,则可以使用更简单、更安全的字符串处理方法,例如:
#include <string>
std::wstring fingers = std::to_wstring(candidate[i].FingerNumber);
m_ListCtrlCandidates.SetItemText(i, 1, fingers.c_str());
(尽管这与老式 MFC 和 CString 的混合程度如何是另一个问题。)