なべひろBlog

プログラミングをメインに仕事に関するアレコレを発信しています。

C#で数値入力の補助をしてみる

C#で数値「だけ」を入力させるコードは世の中にたくさんあります。

ベタな手法でWinFormsだとKeyPressイベントで数値か否かをチェックしてイベントをキャンセル状態にしますね。

必要に応じて符号などもOKな条件を追記すれば符号あり、小数点ありの数値入力も可能です。

しかしいろんなケースを考えるとそれでは完璧に数値に変換できる文字列とするのは厳しいです。

数値のど真ん中に符号を入力されたり、数値を入れる前に小数点を入れられたり、小数点が複数あったりする可能性もあります。

利用者に完璧を求めてはいけません。

どんなに有能な人でもミスはします。

ミスをする事を前提にプログラムを作れば後でトラブルになる事のないプログラムが作れます。

という事でどんな入力があっても頑張って数値化できるようなプログラムを作ってみました。

private string checkNumber(string str)
{
    // 先頭がカンマなら先頭に0を加える(まずは必要な数値を追加)
    if (str.IndexOf('.') == 0)
        str = '0' + str;
    //先頭が符号で次がカンマの場合0を加える
    if ((str.IndexOf('+') == 0 || str.IndexOf('-') == 0) && str.IndexOf('.') == 1)
    {
        str = str.Insert(1, "0");
    }
    bool comma = false;
    // 一度文字列をchar配列に分解して1文字ずつチェック
    char[] array = str.ToCharArray();
    for (int i = 0; i < array.Length; i++)
    {
        // 最初に出現したカンマ以外は文字に変換(後で正規表現で削除)
        if (array[i] == '.' && comma == false)
        {
            comma = true;
        }
        else if (array[i] == '.' && comma == true)
        {
            array[i] = 'a';
        }
        // 先頭以外に出現した+や-は文字に変換(後で正規表現で削除)
        if (i != 0 && (array[i] == '+' || array[i] == '-'))
        {
            array[i] = 'a';
        }
    }
    // char配列を文字列にして正規表現で「a」を消して返す
    return System.Text.RegularExpressions.Regex.Replace(new string(array), @"[^0-9.+-]", "");
}

符号や小数点のチェックをした後に数値のルールにそぐわない物は一度仮の文字に置き換えて正規表現で葬り去りますw

たぶんね、もっとスマートなやり方があると思いますが、何をやっているかの仕組みを理解するにはベタに書いた方が理解しやすいですよね(言い訳)