IsDigit 및 IsNumber 함수를 오용하지 마십시오.
6347 단어 number
최근에 프로그램에 TextBox 숫자의 입력을 제어하는 코드가 있다는 것을 발견했습니다. 여러분은 다음과 같이 낯설지 않을 거라고 믿습니다.
void int_KeyPress(object sender, KeyPressEventArgs e)
{
const char Delete = (char)8;
if (!Char.IsDigit(e.KeyChar) && e.KeyChar != Delete)
{
e.Handled = true;
}
}
언뜻 보기에는 아무런 문제가 없는 것 같지만, 0, 1, 2, 3 등 전각의 숫자를 입력할 수 있는 버그가 생겼다.오류의 근원은 바로 위 코드에서 사용된 IsDigit 함수이다. 그래서 다음과 같은 탐구가 생겼다. IsDigit 함수의 진면목을 살펴보자.
2. IsDigit 함수
MSDN을 찾아보면 함수가 유니코드의 십진수를 판단하는 함수임을 알 수 있습니다.소스 코드 보기
public static bool IsDigit(char c)
{
if (!IsLatin1(c)) return CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;
return c >= '0' && c <= '9';
}
첫 줄의 IsLatin1 함수는 문자가 0~255인 것을 판단하는 함수인데 전각의 0, 1, 2, 3 등의 유니코드 인코딩은 이 범위에 있지 않기 때문에 아래의 코드를 집행했다.
CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber;
유니코드의 분류에서 반각의 1,2,3과 전각의 0,1,2,3 등은 모두DecimalDigitNumber로 분류되기 때문에 전각의 숫자에 대해 이 함수는true로 되돌아간다.또 하나의 함수인 IsNumber와 IsDigit의 기능이 비슷한데, 우리가 그것으로 대체할 수 있습니까?다음 분석을 보겠습니다.
3. IsNumber 함수는 또 무엇입니까?
이 함수의 정의를 먼저 봅시다.
public static bool IsNumber(char c)
{
if (!IsLatin1(c)) return CheckNumber(CharUnicodeInfo.GetUnicodeCategory(c));
if (!IsAscii(c)) return CheckNumber(GetLatin1UnicodeCategory(c));
return c >= '0' && c <= '9';
}
internal static bool CheckNumber(UnicodeCategory uc)
{
switch (uc)
{
case UnicodeCategory.DecimalDigitNumber:
case UnicodeCategory.LetterNumber:
case UnicodeCategory.OtherNumber:
return true;
}
return false;
}
IsDigit 함수와 비교하면 세 가지 차이가 있습니다: 1) 유니코드 Category가 하나 더 있습니다.LetterNumber 유형
2)유니코드 Category가 하나 더 있습니다.Othernumber 유형
3) IsAscii의 판단이 하나 더 생겼다(0~127)
IsNumber의 범위가 더 넓어진 것은 분명하다.다음은 IsNumber가 숫자로 간주하는 몇 가지 문자를 열거한다
UnicodeCategory.LetterNumber:Ⅰ、Ⅱ、Ⅲ
UnicodeCategory.OtherNumber:①、②、③
128~255 중 어떤 문자가 IsNumber에 의해 숫자로 여겨지는지 관심 있는 사람은 스스로 테스트할 수 있다.
테스트 방법은 이 함수를 이용할 수 있다: 시스템.Globalization.CharUnicodeInfo.Get Unicode Category (char c) 는 Unicode Category 형식으로 되돌아옵니다. IsNumber의 몇 가지 유형인지 보시면 알 수 있습니다.
4. 결론
위의 두 함수의 내부 실현을 규명하면 ASCII 숫자(0~9)인지 판단할 때 다음과 같은 몇 가지를 주의해야 한다.
1) IsDigit과 IsNumber 함수로 ASCII 숫자인지 아닌지를 판단할 수 없으며, 이 두 함수 모두 ASCII 이외의 일부 문자를 숫자로 간주할 수 있다.
2) 가능한 한 이런 방식으로 판단한다: c>='0'& c<='9'(물론 정규 표현식도 사용할 수 있다).
3) 숫자판단의 엄격성은 엄격함에서 느슨함까지 다음과 같다.
c >= '0' && c <= '9' ⇒IsDigit ⇒IsNumber
4) 위의 버그 함수 수정을 끝으로
void int_KeyPress(object sender, KeyPressEventArgs e)
{
const char Delete = (char)8;
if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && e.KeyChar != Delete)
{
e.Handled = true;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
숫자와 문자숫자의 기초적인 개념 자바 스크립트에서 숫자라는 개념은 다른 언어와는 다르게 int double float long short 이렇게 숫자의 타입을 엄격하게 세분화 하지 않고 크게 number로 사용한다. 위의 코드...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.