在处理汉字(宽)时,我的应用程序在发行版中表现得很奇怪。 我在调试模式下抛出调试断言的行如下:
str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());
(str是std :: wstring的地方) 在调试模式下,此行引发断言。我知道这是因为 isspace 无法处理宽字符。代替 isspace ,我必须使用 iswspace 。
str.erase(std::remove_if(str.begin(), str.end(), isspace), str.end());
if (!str.empty())
{ // add str to GUI }
如果在调试断言中按“ 忽略”,则会将 str 正确添加到GUI。 但是在发布模式下, str 不会添加到GUI。
但是,如果我使用 iswspace ,则会将 str 正确添加到GUI中,而无需对添加到GUI逻辑进行任何更改。
更奇怪的是,在发布模式期间,某些中文字符也已正确添加到GUI中。 例如,当str为 L“左” 时,会将str添加到GUI。但当它为 L“右” 时未添加到GUI。
有人遇到过这个问题吗?
我的理解是处于发布模式,因此不会考虑调试断言,并且其工作原理类似于'忽略'。
编辑:
我进一步调试了它(在发行版中)。在 L“右” 的情况下,if(!str.empty())似乎不会进入内部。但是,Visual Studio调试器在if条件下达到断点时,仍在str内部显示L“右”。
编辑2:
我在str.erase行上方添加了std::locale::global(std::locale(""));
。
现在,它在调试和发布情况下的工作原理完全相同,并且文本已添加到GUI。
这里是一个例子:
#include <string>
#include <iostream>
#include <algorithm>
int main(int argc, char* argv[])
{
std::wstring str1 = L"左";
std::wstring str2 = L"右";
str1.erase(std::remove_if(str1.begin(), str1.end(), isspace), str1.end());
if (!str1.empty())
{
std::wcout << L"str1 not empty\n";
}
str2.erase(std::remove_if(str2.begin(), str2.end(), isspace), str2.end());
if (!str2.empty())
{
std::wcout << L"str2 not empty\n";
}
getchar();
return 0;
}
此打印仅显示“ str1不为空”。
答案 0 :(得分:5)
答案 1 :(得分:2)
我的理解是处于发布模式,因此不会考虑调试断言,并且其工作方式类似于“忽略”。
是的,但是您忽略了未定义的行为,因为您正在将超出范围的值传递给isspace
。
阅读documentation,了解您使用的功能:
如果
ch
的值不能表示为unsigned char
并且不等于EOF
,则行为不确定。
真的,您不应为此使用isspace
。使用支持您正在使用的任何编码的库(UTF-8?UTF-16?)
答案 2 :(得分:1)
对宽字符串使用iswspace(及其宽字符弟兄):
#include <string>
#include <algorithm>
#include <iostream>
int main(int argc, char* argv[])
{
std::wstring str1 = L"左";
std::wstring str2 = L"右";
str1.erase(std::remove_if(str1.begin(), str1.end(), iswspace), str1.end());
if (!str1.empty())
{
std::wcout << L"str1 not empty\n";
}
str2.erase(std::remove_if(str2.begin(), str2.end(), iswspace), str2.end());
if (!str2.empty())
{
std::wcout << L"str2 not empty\n";
}
getchar();
return 0;
}
输出:
str1 not empty
str2 not empty
在发布模式或调试模式下,isspace
版本是“有效”还是“无效”都是红色鲱鱼,因为您一直在调用未定义的行为:
CppReference.com on isspace,请强调:
如果ch的值不能表示为
unsigned char
并且不等于EOF
,则行为未定义。