printfスタイルの文字列フォーマット


9

チャレンジ

C printfスタイルの文字列フォーマットを実装する関数を記述します。

ルール

  1. あなたは必要があり、少なくとも実装%%%c%s%d%f
  2. あなたはいけません、組み込みの文字列の書式設定の方法を使用します。
  3. あなたはしてはならない外部プログラムを実行したり、あなたのプログラムからインターネットに接続します。
  4. 無効な入力の処理方法はユーザーが決定しますが、プログラムが異常終了してはなりません
  5. あなたはすべき書く可変引数機能を可能な場合。

このドキュメントのキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」、および「OPTIONAL」は、RFC 2119で説明されているように解釈されます


何をし%cますか?かなり確信して%s%dおよび%f文字列、int型や山車respectivellyが、わからない程度のためのものです%c
Sumurai8 2014年

%c渡されたint IIRCのASCII値を表示します
marinus

文字を出力するので97'a'両方ともa出力されます。
nyuszika7h 2014年

%-02d右のようなフォームをサポートする必要はありませんか?その3つの%c、%s、%d?
YOU

@YOU正解。もういい。
nyuszika7h 2014年

回答:


4

APL(73)

{⊃,/,⌿↑(⊂2∘↓¨Z⊂G),⊂{'c'0≡⍵,∊⊃⍺:⎕UCS⍺⋄⍕⍺}/⍵,⍪⌷∘G¨1↓1+(Z←G='%')/⍳⍴G←'%!',⍺}

いくつかのテスト:

      'a:%c b:%s c:%d'{⊃,/,⌿↑(⊂2∘↓¨Z⊂G),⊂{'c'0≡⍵,∊⊃⍺:⎕UCS⍺⋄⍕⍺}/⍵,⍪⌷∘G¨1↓1+(Z←G='%')/⍳⍴G←'%!',⍺} 65 'foo' 67
a:A b:foo c:67 

      printf←{⊃,/,⌿↑(⊂2∘↓¨Z⊂G),⊂{'c'0≡⍵,∊⊃⍺:⎕UCS⍺⋄⍕⍺}/⍵,⍪⌷∘G¨1↓1+(Z←G='%')/⍳⍴G←'%!',⍺}
      '1:%s 2:%s 3:%d 4:%c 5:%c' printf 'foo' 'bar' 100 110 'z'
1:foo 2:bar 3:100 4:n 5:z   
      'The %s brown %c%c%c jumps over the %s dog.' printf 'quick' 102 111 'x' 'lazy'
The quick brown fox jumps over the lazy dog.

説明:

  • G←'%!',⍺:ダミー指定子を文字列の前に付ける(処理を容易にするため)
  • (Z←G='%')/⍳⍴G%文字列内のすべての文字のインデックスを検索します。また、ビットマスクを格納しますZ
  • ⌷∘G¨1↓1+:の横にあるすべての文字を選択し%、ダミーをドロップします。
  • ⍵,⍪:各指定子を正しい引数の値と一致させます。
  • {... }/:各ペアで次の関数を実行します。
    • 'c'0≡⍵,∊⊃⍺:引数が数値で、指定子がc
    • :⎕UCS⍺:次に、引数のUnicode値を返します。
    • ⋄⍕⍺:それ以外の場合は、引数の文字列表現を返します。
  • :同封
  • ⊂2∘↓¨Z⊂G:文字列を%sで分割してから、各部分文字列の最初の2文字を削除し(ここでダミーが入ります)、その結果を囲みます。
  • :2つの囲まれた配列から行列を作成し、各部分文字列とそれに続く値を一致させます。
  • ,⌿:各部分文字列とその値を結合します。
  • ⊃,/:次に、結果の文字列を結合します。

意味不明なように見える難解な言語を見るのはいつも楽しいです。;)
nyuszika7h 2014年

2
@ nyuszika7h:これは実際には深刻な言語です。それは1960年代にさかのぼり、それはまだ使用されています。それはゴルフをしていなかった場合、それは意味不明なもののように少し少なく見えるでしょう。
マリナス2014年

なるほど、面白いです。
nyuszika7h 2014年

@ nyuszika7h:まあ、技術的にはリスト指向のプログラミング言語なので、コードゴルフ用に設計されていると言えるでしょう。特に、プログラムをより読みやすく冗長にすることを目的とした特殊な文字セットを使用していることを考えると、そして、それはJプログラミング言語とGolfScriptにインスピレーションを与えました。
Konrad Borowski、2014年

@xfix LISPはリスト指向のプログラミング言語だと思いましたか?私たちは大学でAPLを実際の作業に使用しました。ネイティブで配列を処理できることは本当に便利です。JはAPLの発明者の1人がその「後継者」として設計したものです。もちろん、コードゴルフに役立たないわけではありません...
Jerry Jeremiah

2

ルビ:102文字

f=->s,*a{s.gsub(/%(.)/){$1==?%??%:a.shift.send({?c=>:chr,?s=>:to_s,?d=>:to_i,?f=>:to_f}[$1])rescue$&}}

サンプルの実行:

irb(main):001:0> f=->s,*a{s.gsub(/%(.)/){$1==?%??%:a.shift.send({?c=>:chr,?s=>:to_s,?d=>:to_i,?f=>:to_f}[$1])rescue$&}}
=> #<Proc:0x96634ac@(irb):1 (lambda)>

irb(main):002:0> puts f["percent : %%\n   char : %c or %c\n string : %s or %s or %s\ndecimal : %d or %d or %d\n  float : %f or %f or %f\ninvalid : %x or %s or %d or %f", 65, 'B', 'format me', 42, Math::PI, 42, Math::PI, '2014', 42, Math::PI, '2014', 'more']
percent : %
   char : A or B
 string : format me or 42 or 3.141592653589793
decimal : 42 or 3 or 2014
  float : 42.0 or 3.141592653589793 or 2014.0
invalid : %x or  or 0 or 0.0
=> nil

無効なフォーマット指定子はそのまま残ります。引数値のないフォーマット指定子は、指定されたタイプの空の値で置き換えられます。


匿名関数を指定できるので、先頭をドロップしますf

確かに。しかし、私が覚えているように、これを投稿した時点では、匿名の機能は満場一致で受け入れられていませんでした。今のところ、Luaの回答は匿名関数に更新されていません(同じ量の文字を節約するため)ので、更新キャンペーンを開始しないと思います。
manatwork

2

Lua 5.2、115バイト

-- Function definition, 115 chars
function f(f,...)n,t=0,{...}return(f:gsub('%%(%a)',function(s)n=n+1return(({c=s.char})[s]or tostring)(t[n])end))end

-- Usage example
print(f('Happy %cew %d %s %f',78,2014,'Year!',math.pi))
-- Output: Happy New 2014 Year! 3.1415926535898

良いですね。Luaのどのバージョンですか?5.1.5は、「 '1return'に近い不正な番号」を示します。「%c」の小さな問題です。78ではなく「N」で失敗します。それとも、私の古いLuaの特性だけですか?
manatwork 2014年


ええ、そこで働きます。
manatwork 2014年

Lua 5.2.3で動作します。
nyuszika7h 2014年

1

C ++(281文字)

#include<sstream>
#include<cstdarg>
#define q(x)va_arg(v,x);break;case
std::string p(char*f,...){std::ostringstream r;va_list v;va_start(v,f);while(*f)if(*f=='%')switch(++f,*f++){case's':r<<q(char*)'d':r<<q(int)'c':r<<(char)q(int)'%':r<<'%';}else r<<*f++;va_end(v);return r.str();}

私はC ++が嫌いですが、それは良い選択のように思えました(そうでない場合は、実際にはCをchar*使用します。char*引数を取ってstd::string結果を出しますが、ねえ、それはC ++なので、(それ自体が一貫性のない言語で)誰が一貫性を気にしますか?


メイン関数がないため、これはコンパイルされません。
nyuszika7h 2014年

@ nyuszika7h:問題は、ではなく関数を作成することでしたmain。しかし、サンプルが必要な場合はmaingist.github.com / xfix / 8238576を試してください(この関数をテストするときに使用しました)。
Konrad Borowski、2014年

確かに、意味のあるmain関数を実際に作成することはできません。関数を追加すると、文字数が増えるだけです。コードを変更したくない場合は、付随するヘッダーファイルと#includeテストプログラムからのヘッダーファイルを追加できます。
nyuszika7h 2014年

1

Java201 186 174バイト

Kevin Cruijssenのおかげで12バイト

String f(String s,Object...a){String r="";for(char c,i=0,j=0;i<s.length();r+=c==37?(c=s.charAt(i++))<38?c:c==99?(char)(int)a[j++]:a[j++]:c==37?"":c)c=s.charAt(i++);return r;}

オンラインでお試しください!


完全にはわかりませんが、=s.charAt(0)から削除できると思いますchar c=s.charAt(0)私がそうするとき、それはまだTIOで働きます。
Kevin Cruijssen、2017年

@KevinCruijssenかなり賢いことを誓います。
Leaky Nun

久しぶりですが、直接印刷することでさらに8バイトを節約できます:void f(String s,Object...a){for(char c,i=0,j=0;i<s.length();System.out.print(c==37?(c=s.charAt(i++))<38?c:c==99?(char)(int)a[j++]:a[j++]:c==37?"":c))c=s.charAt(i++);} 166バイト(さらにJava 8に変換することでさらに増えることもありますが、実際にはそうではありません)
Kevin Cruijssen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.