challenge printfの自作

printf関数を自作してください。
printfの説明は不要だと思います。とりあえずWikiPediaのリンクをはっておきます。

実際にはsprintf関数を作ってください。
注意事項
  • 標準でついているprintf系関数の使用禁止
  • 標準でついているライブラリ以外の使用禁止
  • 引数・返り値等の仕様はできるだけ似せればよい

可変長引数など、言語によっては難しい/不可能な仕様もありますが、いろいろ工夫して本物に近づくようにしてみてください。
1
2
3
4
5
6
7
#include <string.h>

// なにもフォーマットしてない
int mysprintf(char *str, const char *format, ... ){
    strcpy(str, format);
    return strlen(str);
}

Posted feedbacks - JavaScript

多分、printfのオリジナルの仕様の5分の1とかくらいなんじゃないかと思うんですが・・・

全部やってたらキリが無いので、 一旦アップします。 もし、「ここの実装だけは行って欲しい」と言う仕様があったら、コメント下さい。 追加で作ってみます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//WScript.Echo( printf("%5x%x", 1234, 1234 ) );
//WScript.Echo( printf("%5d%d", "F", "F" ) );
//WScript.Echo( printf("%5o%o", 1234, 1234 ) );
//WScript.Echo( printf("%%%%", 1234, 1234 ) );

function printf(){
  var re = RegExp, arg = arguments, s = arg[0];
  var _ = {
    'd' : function(a,$){return RPAD( eval("0x" + a).toString(10) ,$ );} ,  //10進
    'o' : function(a,$){return RPAD( eval( a.toString() ).toString(8)  ,$ );} ,  //8進
    'x' : function(a,$){return RPAD( eval( a.toString() ).toString(16) ,$ );} ,  //16進(小文字)
    '%' : function(a,$){return '%';}
  };
  var mk = [];
  for(var key in _) mk.push(key);
  var r = "%(\\d\*)(" + mk.join("|") + ")";
  for(var i = 1; i < arg.length; i++) {
    if( !s.match(r) ) continue;
    var x = re.$1 || 0, y = re.$2;
    s = s.replace( re(r), _[y]( arg[i] + "", x ) );
  }
  return s;
  function RPAD( s, len ){ while( s.length < (len - 0) ) s += ' ';    return s; }
  function LPAD( s, len ){ while( s.length < (len - 0) ) s = ' ' + s; return s; }
}

要求仕様どころか、バグってましたね。 申し訳無いです。 修正します。

っていうか、

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//WScript.Echo( printf("%5x%x", 1234, 1234 ) );
//WScript.Echo( printf("%5d%d", "F", 10 ) );
//WScript.Echo( printf("%5o%o", 1234, 1234 ) );
//WScript.Echo( printf("%%%%", 1234, 1234 ) );

function printf(){
  var re = RegExp, arg = arguments, s = arg[0];
  var _ = {
    'd' : function(a,$){   //10進
      if( a.match(/[a-fA-F]/) ) return RPAD(eval( "0x" + a.toString() ).toString(10) ,$ );
      else                      return RPAD(eval( a.toString() ).toString(10) ,$ );
    } ,
    'o' : function(a,$){return RPAD( eval( a.toString() ).toString(8)  ,$ );} ,  //8進
    'x' : function(a,$){return RPAD( eval( a.toString() ).toString(16) ,$ );} ,  //16進(小文字)
    '%' : function(a,$){return '%';}
  };
  var mk = [];
  for(var key in _) mk.push(key);
  var r = "%(\\d\*)(" + mk.join("|") + ")";
  for(var i = 1; i < arg.length; i++) {
    if( !s.match(r) ) continue;
    var x = re.$1 || 0, y = re.$2;
    s = s.replace( re(r), _[y]( arg[i] + "", x ) );
  }
  return s;
  function RPAD( s, len ){ while( s.length < (len - 0) ) s += ' ';    return s; }
  function LPAD( s, len ){ while( s.length < (len - 0) ) s = ' ' + s; return s; }
}

Ruby の sprintf を参考にしました。あまりテストしてないのでバグだらけの可能性があります。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
function sprintf(format){
  var args = arguments, x = 1;
  function addZero(s, p){ return ((p -= s.length) > 0) ? Array(p + 1).join(0) + s : s }
  return String(format).replace(
    /%(?:(\d+)\$)?([-+ #0]*)(\d*|\*(?:(\d+)\$)?)(?:\.(\d+|\*(?:(\d+)\$)?))?([diubBoOxXeEfFgGaAcsp%])/g,
    function($, pos_s, flag, width, pos_w, prec, pos_p, type){
      if(type === '%') return '%';
      if(~width.indexOf('*')) width = pos_w > 0 ? args[pos_w] : args[x++];
      prec = prec === undefined ? -1
        : ~prec.indexOf('*') ? (pos_p > 0 ? args[pos_p] : args[x++]) : +prec;
      var r = '', a = pos_s > 0 ? args[pos_s] : args[x++], sharp = ~flag.indexOf('#');
      var sign = a < 0 && (a *= -1) ? '-' : ~flag.indexOf('+') ? '+' : ~flag.indexOf(' ')?' ':'';
      switch(type){
       case'd': case'i': r = !r && prec == 0 ? '' : sign + addZero(''+ (a | 0), prec); break;
       case'u':
        a = sign == '-' ? (sign = '', 0x100000000 - (a | 0)) : a | 0;
        r = sign + addZero(''+ a, prec); break;
       case'b': case'B': r = sign + (sharp ? '0b' : '') + addZero((+a).toString(2),  prec); break;
       case'o': case'O': r = sign + (sharp ? '0'  : '') + addZero((+a).toString(8),  prec); break;
       case'x': case'X': r = sign + (sharp ? '0x' : '') + addZero((+a).toString(16), prec); break;
       case'f': case'F':
        r = sign + (+a).toFixed(~prec ? prec : 6);
        if(!prec && sharp) r += '.'; break;
       case'e': case'E':
        r = sign + (+a).toExponential(~prec ? prec : 6);
        if(!prec && sharp) r = r.replace(/e/, '.e'); break;
       case'g': case'G':
        r = sign + (+a).toPrecision(~prec ? prec : 6);
        if(!sharp) r = r.replace(/\.?0+(?=e|$)/, '');
        break;
       case'a': case'A':
        r = sign + (+a).toString(16);
        if(~prec) r = r.replace(/([^.]+)\.?([^\(]*)(.*)/, function(i,d,e){
          return i + (prec ? '.'+ (d +'0000000000000').substr(0, prec) + e : sharp?'.':'') });
       case'c': r = String.fromCharCode(a | 0); break;
       case'p': if(typeof uneval == 'function') a = uneval(a); // fallthrough
       case's': r += ~prec ? a.substr(0, prec) : a; break;
      }
      if(/[BXEGA]/.test(type)) r = r.toUpperCase();
      if((width -= r.length) > 0){
        var t = Array(width + 1).join(~flag.indexOf(0) && /[^cs]/.test(type) ? 0 : ' ');
        r = ~flag.indexOf('-') ? r + t : t + r;
      }
      return r;
    });
}

Index

Feed

Other

Link

Pathtraq

loading...