C# 入門 & 実践 / C sharp

4-17. 文字列操作 - 3 - フォーマット, sprintf


・文字列中に設定された書式項目のプレースホルダを、対応する数値、日付、時刻、または列挙値のテキスト表現に置き換えるには、Format を使用。

Format を見るときに思ったのが、sprintf はあるのか?と思い。
なんとC#には sprintf が無いんです!それに変わるものも無いようで^0^;
ということで、Format を見た後に、sprintf っぽくしてみます。

Format


これは、サンプルをそのままですが、基本的にこの一覧があると使いやすいですね。
    class MyString
    {
        enum Color { Yellow = 1, Blue, Green };
        static DateTime thisDate = DateTime.Now; 

         static void Main()
        {
             string s = "";
             // 数値、金額、時刻の変換にするようです。
             Console.WriteLine("数値フォーマット");
             s = String.Format(
                 "(C)  Currency: {0:C}\n" +
                 "(D)  Decimal: {0:D}\n" +
                 "(E)  Scientific: {1:E}\n" +
                 "(F)  Fixed  point: {1:F}\n" +
                 "(G)  General: {0:G}\n" +
                 "     (default): {0}  (default  =  'G')\n" +
                 "(N)  Number: {0:N}\n" +
                 "(P)  Percent:{1:P}\n" +
                 "(R)  Round-trip:{1:R}\n" +
                 "(X)  Hexadecimal:{0:X}\n",   -123,  -123.45f);
             Console.WriteLine(s);

             Console.WriteLine("日付時刻フォーマット");
             s = String.Format(
                  "(d)  Short  date:{0:d}\n" +
                  "(D)  Long  date:{0:D}\n" +
                  "(t)  Short  time:{0:t}\n" +
                  "(T)  Long  time:{0:T}\n" +
                  "(f)  Full  date/short  time:{0:f}\n" +
                  "(F)  Full  date/long  time:{0:F}\n" +
                  "(g)  General  date/short  time:{0:g}\n" +
                  "(G)  General  date/long  time:{0:G}\n" +
                  "     (default):{0}  (default  =  'G')\n" +
                  "(M)  Month:{0:M}\n" +
                  "(R)  RFC1123:{0:R}\n" +
                  "(s)  Sortable:{0:s}\n" +
                  "(u)  Universal  sortable:{0:u}  (invariant)\n" +
                  "(U)  Universal  sortable:{0:U}\n" +
                  "(Y)  Year:{0:Y}\n",
                  thisDate);
             Console.WriteLine(s);

             Console.WriteLine("Enumフォーマット");
             s = String.Format(
                 "(G)  General:{0:G}\n" +
                 "     (default):{0}  (default  =  'G')\n" +
                 "(F)  Flags:{0:F}  (flags  or  integer)\n" +
                 "(D)  Decimal  number:{0:D}\n" +
                 "(X)  Hexadecimal:{0:X}\n",
                 Color.Green);
             Console.WriteLine(s); 
        }
    }

数値フォーマット
(C) Currency: -3
(D) Decimal: -123
(E) Scientific: -1.234500E+002
(F) Fixed point: -123.45
(G) General: -123
(default): -123 (default = 'G')
(N) Number: -123.00
(P) Percent:-12,345.00%
(R) Round-trip:-123.45
(X) Hexadecimal:FFFFFF85

日付時刻フォーマット
(d) Short date:2006/09/13
(D) Long date:2006年9月13日
(t) Short time:17:21
(T) Long time:17:21:13
(f) Full date/short time:2006年9月13日 17:21
(F) Full date/long time:2006年9月13日 17:21:13
(g) General date/short time:2006/09/13 17:21
(G) General date/long time:2006/09/13 17:21:13
(default):2006/09/13 17:21:13 (default = 'G')
(M) Month:9月13日
(R) RFC1123:Wed, 13 Sep 2006 17:21:13 GMT
(s) Sortable:2006-09-13T17:21:13
(u) Universal sortable:2006-09-13 17:21:13Z (invariant)
(U) Universal sortable:2006年9月13日 8:21:13
(Y) Year:2006年9月

Enumフォーマット
(G) General:Green
(default):Green (default = 'G')
(F) Flags:Green (flags or integer)
(D) Decimal number:3
(X) Hexadecimal:00000003

sprintf っぽく


stringのメソッドを組み合わせて。
sprintfを機能させるというより、stringのメソッドの練習程度です^-^;
        static void Main()
        {
             string s = "";

             int i = 123;
             float f = 4.5F;

             string str_i = i.ToString().PadLeft(5,'0');
             string[] str_f_array = f.ToString().Split( '.' );
             string str_f = str_f_array[0].PadLeft(8, '0') + "." + str_f_array[1].PadRight(3, '0');

             s = String.Format(
                 "%05d : {0}\n" +
                 "%08.2f: {1}\n"
                 ,  str_i , str_f );
             Console.WriteLine(s);

             Console.WriteLine("勝手に sprintf !!! ");
             // 適当に作った sprintf を使う
             string[] formats ={"10d","s","5.5f"};
             object[] args = { i, f ,f};
             s = sprintf(
                 "%010d : {0}\n" +
                 "%s: {1}\n" +
                 "%05.5f: {2}" , formats,args);
             Console.WriteLine(s);
        }

        public static string sprintf( string format , string[] formats, object[] args ){
            string[] strings = new string[args.Length];

            for (int i = 0; i < args.Length; i++)
            {
                strings[i] = sf(formats[i], args[i]);
            }
            return String.Format(format, strings);
        }
        // 変換
        public static string sf(string format, object arg)
        {

            string s = arg.ToString();
            string end = format[format.Length -1 ].ToString();

            int keta = 5;
            // d, f, sだけだとして最後の文字を比較
            switch( end )
            {
                case "s":
                    return s;
                case "d":
                    keta = Int32.Parse( string.Format("{0:D}", format.Remove(format.Length - 1)) );
                    return s.PadLeft(keta , '0');
                case "f":
                    string[] sa = format.Remove(format.Length - 1).Split('.');
                    string[] sd = s.Split('.');
                    if (sa[0].Length > 0)
                    {
                        keta = Int32.Parse(sa[0]);
                        sd[0] = sd[0].PadLeft(keta, '0');
                    }
                    if (sd[1].Length > 0)
                    {
                        keta = Int32.Parse(sa[1]);
                        sd[1] = sd[1].PadRight(keta, '0');
                        s = sd[0] + "." + sd[1];
                    }
                    return s;
            }
            return "";
            
        }
%05d : 00123
%08.2f: 00000004.500

勝手に sprintf !!!
%010d : 0000000123
%s: 4.5
%05.5f: 00004.50000

まぁこんな感じで。
もう少しで例外処理に入りますので・・・ここはエラーは無視で^-^;




4-16. 文字列操作 - 2 - コピーと変換 « 4. C# 入門 Level 2 » 4-18. 文字列操作 - 4 - 正規化


C# 入門 & 実践 / C sharp