printf 스타일 문자열 형식


9

도전

C printf스타일 문자열 형식 을 구현하는 함수를 작성하십시오 .

규칙

  1. 당신은 해야한다 구현 적어도 %%, %c, %s, %d%f.
  2. 당신은 내장 된 문자열 포맷 방법을 사용합니다.
  3. 당신은 외부 프로그램을 실행하거나 프로그램에서 인터넷에 연결할 수 있습니다.
  4. 유효하지 않은 입력을 처리하는 방법은 사용자의 결정에 달려 있지만 프로그램 비정상적으로 종료 되지 않아야 합니다.
  5. 당신은 해야 된 기록 가변 기능이 가능한 경우.

이 문서의 핵심 단어 "MUST", "MUST NOT", "필수", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY"및 "OPTIONAL" RFC 2119에 설명 된 대로 해석됩니다 .


무엇을 %c합니까? 확신 %s, %d그리고 %f문자열의 int와 수레 respectivelly하지만 확신에 대한위한 것입니다 %c.
Sumurai8

%c전달 된 int IIRC의 ASCII 값을 표시합니다.
marinus

그것은 문자를 인쇄, 이렇게 97하고 'a'모두가 될 a출력에.
nyuszika7 시간

%-02d올바른 형식을 지원할 필요가 없습니까? 그 세 % c, % s, % d?
당신

@YOU 맞습니다. 충분 해.
nyuszika7 시간

답변:


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+: %s 옆의 모든 문자를 선택 하고 더미를 놓습니다.
  • ⍵,⍪: 각 인수를 올바른 인수의 값과 일치시킵니다.
  • {... }/: 각 쌍에서 다음 기능을 실행하십시오.
    • 'c'0≡⍵,∊⊃⍺: 인수가 숫자이고 지정자 인 경우 c:
    • :⎕UCS⍺: 그런 다음 인수의 유니 코드 값을 반환합니다.
    • ⋄⍕⍺그렇지 않으면 인수의 문자열 표현을 리턴합니다.
  • : 동봉
  • ⊂2∘↓¨Z⊂G: %s 에서 문자열을 분할 한 다음 각 하위 문자열의 처음 두 문자 (더미가 나오는 곳)를 제거하고 그 결과를 묶습니다.
  • : 두 개의 닫힌 배열로 행렬을 만들고 각 하위 문자열을 따라야하는 값과 일치시킵니다.
  • ,⌿: 각 하위 문자열을 값으로 결합합니다.
  • ⊃,/: 그런 다음 결과 문자열을 결합합니다.

횡설수설처럼 보이는 난해한 언어를 보는 것이 항상 재미 있습니다. ;)
nyuszika7h

2
@ nyuszika7h : 이것은 실제로 심각한 언어입니다. 그것은 1960 년대에 만들어졌으며 여전히 사용되고 있습니다. 골프를 치지 않았다면 횡설수설처럼 보이지 않을 것입니다.
marinus

흥미 롭습니다.
nyuszika7 시간

@ nyuszika7h : 기술적으로 목록 지향 프로그래밍 언어이므로 코드 골프 용으로 설계되었다고 말할 수 있습니다. 특히 프로그램을 더 읽기 쉽고 덜 이해하기위한 특수 문자 세트를 사용한다는 점을 고려할 때 특히 그렇습니다. J 프로그래밍 언어 와 GolfScript에 영감을 주었습니다.
Konrad Borowski

@xfix LISP가 목록 지향 프로그래밍 언어라고 생각 했습니까? 우리는 실제 작업에 대학에서 APL을 사용했습니다. 기본적으로 배열을 처리 할 수있는 것이 정말 편리합니다. J는 APL의 발명가 중 한 사람에 의해 "후임자"로 설계되었습니다. 물론 이것이 코드 골프에 유용하지 않다는 것을 의미하지는 않습니다.
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
cat

과연. 그러나 내가 기억할 때, 이것을 게시 할 때 익명의 기능은 만장일치로 받아 들여지지 않았습니다. 현재 Lua 답변은 익명의 기능으로 업데이트되지 않았지만 (같은 양의 문자를 저장하기 위해) 업데이트 캠페인을 시작하지 않을 것이라고 생각합니다.
manatwork

2

루아 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

좋은데 루아의 어떤 버전? 5.1.5는“ '1return'근처의 잘못된 숫자를 나타냅니다. “% c”의 작은 문제로 78이 아닌 'N'에서 실패합니다. 아니면 내 오래된 루아의 특이성입니까?
manatwork


pp, 거기서 일한다.
manatwork

Lua 5.2.3에서 작동합니다.
nyuszika7 시간

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 ++를 싫어하지만 좋은 선택처럼 보였다 ( char*포인터가 실제로 유용하기 위해서는 너무 많은 노력이 필요 하지 않으면 실제로 C와 함께 갈 것이다 ). 소요 char*인수 및 std::string++, 그래서 누가 (그 자체가 일치하지 않는 것을 언어)의 일관성에 대한 관심 C있어 그, 헤이 결과 만을?


주요 기능이 없으므로 컴파일되지 않습니다.
nyuszika7h

@ nyuszika7h : 문제는 함수가 아니라 함수를 만드는 것 main입니다. 그러나 sample이 필요한 경우 gist.github.com/xfix/8238576을main 사용해보십시오 (이 기능을 테스트하는 동안 사용했습니다).
Konrad Borowski

사실, 실제로 의미있는 main기능을 만들 수는 없습니다. 하나만 추가하면 문자 수가 증가합니다. 코드를 수정하지 않으려면 #include테스트 프로그램에서 헤더 파일과 파일을 추가 할 수 있습니다 .
nyuszika7 시간

1

자바 , 201 (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

@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.