数値を表す文字列
タイトル:文字列が値(整数と小数を含む)を表すかどうかを判別する関数を実装してください。
たとえば、文字列「+100」、「5e2」、「-123」、「3.1416」、「-1E-16」すべて数値を意味します
が、「12e」、「1a3,14」、「1.2.3」、「±5」、「±5」、「12e5.4」はそうではありません。
表現モード
表示される値の文字列パターンは、
A [。[B]] [e | EC]または.B [e | EC]
であると結論付けることができます。ここで、Aは値の整数部分であり、Bの後に小数点が続きます。は値の小数部分です。Cの直後に「e」または「E」が続くのは値の指数部分です。
小数には値の整数部分がない場合があります。たとえば、10進数の.123は0.123に等しくなります。したがって、A部分は必要ありません。数値に整数部分がない場合、その小数部分を空にすることはできません。
上記のAとCは、どちらも「+」または「-」で始まる0〜9桁の文字列です。 ; Bも0〜9の数字列ですが、前に記号を付けることはできません
方法
文字列が上記のパターンに準拠しているかどうかを判断するときは、最初に0から9までのできるだけ多くの桁をスキャンします(最初に「+」または「-」がある場合があります)。つまり、次のパターンで購入したお金です。数値整数パートAを表します。
小数点「。」が見つかった場合は、値の小数点を表すB部分のスキャンを開始します。「e」または「E」に遭遇した場合は、パートCのスキャンを開始します
コード
bool isNumberic(const char* str)
{
if(str==nullptr)
return false;
bool numeric=scanInteger(&str);
//如果出现'.',则接下来时数字的小数部分
if(*str=='.')
{
++str;
/*下面一行代码用||的原因
1、小数可以没有整数部分
2、小数点后面可以没有数字,如233.和2333.0
3、当然,小数点前面和后面可以都有数字,如2333.666
*/
numeric=scanUnsignedInteger(&str)||numeric;
}
//如果出现'e'或者'E',则接下来时数字的指数部分
if(*str=='e' || *str=='E')
{
++str;
/*下面一行用&&的原因
1、当e或者E前面没有数字时,整个字符串并不能表示数字,如.e1、e1;
2、当e或者E后面没有整数时,整个字符串不能表示数字,如12e、12e+5.4
*/
numeric==numeric&&scanInteger(&str);
}
return numeric && *str=='\0';
}
//用来扫描字符串中0~9的数位,可以用来匹配前面数值模式中的B部分
bool scanUnsignedInteger(const char** str)
{
const char* before=*str;
while(**str!='\0' && **str>='0' && **str<='9')
++(*str);
//当str中存在若干0~9的数字时,返回true
return *str>before;
}
//扫描可能以表示正负的'+'或者'-'为起始的0~9的数位(类似一个可能带正负符号的整数)
bool scanInteger(const char** str)
{
if(**str=='+' || **str=='-')
++(*str);
return scanUnsignedInteger(str);
}
—————————————————————————————————————————————————— -
参考書「ソードフィンガーオファー」