C#でC言語のprintfもどきを作る

組み込み用なので取りあえず使いそうな機能のみをサポートしています。
何をサポートするかは個人的な独断と偏見です。

仕様

  [ ]は省略可能
  | は選択
  引数は6個まで(拡張可能)
  %[n][d|D]   nカラム確保し、十進数で表示する
  %[n][x|X]   nカラム確保し、十六進数で表示する
  %[m.n][f|F] mカラム確保し、小数点以下n桁で実数を表示する
  %c|C        一文字表示
  %s|S        文字列表示
sprintf.cs
using System;
/*********************************************************************/
/*  C言語のprintf擬きを実現させるためのsprintf機能制限版            */
/*           引数は6個まで(拡張可能)                                 */
/*  %[n][d|D]   nカラム確保し、十進数で表示する                      */
/*  %[n][x|X]   nカラム確保し、十六進数で表示する                    */
/*  %[m.n][f|F] mカラム確保し、小数点以下n桁で実数を表示する         */
/*  %c|C        一文字表示                                           */
/*  %s|S        文字列表示                                           */
/*********************************************************************/

namespace BoeBotLib
{
    class Std
    {
        static object[] obInit(int n){
          object[] val = new object[n];
          for(int i=0; i<val.Length; i++) val[i]=null;
          return val;
        }
        public static String sprintf(String fmt, object val0)
        {
          object[] val = obInit(1);
          val[0]=val0;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, object v0, object v1)
        {
          object[] val = obInit(2);
          val[0]=v0; val[1]=v1;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2)
        {
          object[] val = obInit(3);
          val[0]=v0; val[1]=v1; val[2]=v2;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2, object v3)
        {
          object[] val = obInit(4);
          val[0]=v0; val[1]=v1; val[2]=v2; val[3]=v3;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2, object v3, object v4)
        {
          object[] val = obInit(5);
          val[0]=v0; val[1]=v1; val[2]=v2; val[3]=v3; val[4]=v4;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, 
          object v0, object v1, object v2, object v3, object v4, object v5)
        {
          object[] val = obInit(6);
          val[0]=v0; val[1]=v1; val[2]=v2;val[3]=v3;val[4]=v4;val[5]=v5;
          return sprintf(fmt, val);
        }
        public static String sprintf(String fmt, object[] xval)
        {
            char ch;
            int j = 0;
            char[] str = new char[80];
            char[] types = {'s','c','f','d','x','S','C','F','D','X'};
            int fmtNumber=0;
            String Value;
            int column=0, space;
            for (int i = 0; i < fmt.Length; i++)
            {
                ch = fmt[i];
                if (ch == '%')
                {
                    int last =(i+6>fmt.Length) ? fmt.Length-i : 6; 
                    int k=100, m=0, mm=0;
                    for(mm=0; mm<types.Length; mm++) {
                      int kk = fmt.IndexOf(types[mm], i, last);
                      if(kk!=-1 && kk<k) {k=kk;m=mm;}
                    }
                    if(k==100) k=0;
                    if(k>0) {
                      switch(types[m])
                      {
                        case 'd':
                        case 'D':
                                  column=int.Parse(fmt.Substring(i + 1, k - 1 - i));
                                  int ival = (int)xval[fmtNumber];
                                  Value=ival.ToString();
                                  if(column>0)
                                  {
                                    space = column - Value.Length;
                                    for (int mn = 0; mn < space; mn++) str[j++] = ' ';
                                  }
                                  foreach (char x in Value)
                                      str[j++] = x;
                                  break;
                        case 'x':
                                  bool upper = false;
                                  goto X;                  
                        case 'X':
                                  upper = true;
                               X: column = 0;
                                  column = int.Parse(fmt.Substring(i + 1, k - 1 - i));
                                  int hval=(int)xval[fmtNumber];
                                  Value=hval.ToString(types[m].ToString());
                                  if (!upper) Value = Value.ToLower();
                                  if(column>0)
                                  {
                                    space = column - Value.Length;
                                    for (int mn = 0; mn < space; mn++) 
                                      str[j++] = fmt[i+1]=='0'? '0':' ';
                                  }
                                  foreach (char x in Value)
                                      str[j++] = x;
                                  break;
                        case 'f': 
                        case 'F': 
                                  int point=fmt.IndexOf(".",i,k-i+1);
                                  column=int.Parse(fmt.Substring(i + 1, point - 1 - i));
                                  int low;
                                  low = int.Parse(fmt.Substring(point + 1, k-1-point));
                                  double dval = (double)xval[fmtNumber];
                                  Value=dval.ToString("f"+low);
                                  space = column - Value.Length;
                                  for (int mn = 0; mn < space; mn++) str[j++] = ' ';                                  
                                  foreach (char x in Value)
                                      str[j++] = x;
                                  break;
                        case 'c':
                        case 'C':
                                  char cx='*';
                                  try{
                                    cx = (char)xval[fmtNumber];
                                  }
                                  catch(Exception) {
                                  };
                                  str[j++] = cx;
                                  break;
                        case 's':
                        case 'S': 
                                   String sval = (String)xval[fmtNumber];
                                   foreach(char c in sval)
                                       str[j++] = c;
                                   break;
                      }
                      i = k;  //書式指定の次の文字へ
                      fmtNumber++;
                    }
                }
                else str[j++] = ch;
            }
            return new String(str,0,j);
        }
    }
}


uOLED96G1に表示するテストプログラム



uOLED96G1に表示するテストプログラム
using System;
using Microsoft.SPOT;
using System.Threading;         // 追加
using Microsoft.SPOT.Hardware;  // 追加、参照設定にも追加
using GHI.OSHW.Hardware;        // 追加、参照設定にも追加
using System.IO.Ports;
using BoeBotLib;

namespace uOLED96G1Test
{
    public class Program
    {
        public static void Main()
        {
            uOLED96G1 LCD = new uOLED96G1();      // LCDオブジェクトCOM2を用いる
            int x = -123;
            double y = 45.67;
            char ch = 'A';
            String s = "String";
            int hex = 0xabcd;
            LCD.Print(Std.sprintf("test %5d", x));
            LCD.Print(Std.sprintf("%8.3f", y));
            LCD.Print(Std.sprintf("ch %c", ch));
            LCD.Print(Std.sprintf("%s", s));
            LCD.Print(Std.sprintf("hex %5x", hex));
        }
    }
}