2016-07-21 9 views
1

私は古いスウィフト文字列から新しいスウィフト文字列を定義するには、古いprintfスタイルの文字列フォーマッタを使用しようとしています。可変引数リストでC文字列としてスウィフトの文字列を渡す

私はこれがある限り、私は文字列変数リテラルではなくスウィフト文字列で始めていて正常に動作気づきます。

// OK! 
String(format:"%s", "hello world".cStringUsingEncoding(NSUTF8StringEncoding)) 

// ERROR: argument type '[CChar]?' does not conform to expected type 'CVarArgType' 
let s = "hello world" 
String(format:"%s", s.cStringUsingEncoding(NSUTF8StringEncoding)) 

どうしてですか?

そして、最高の回避策は何ですか?

(私が知っなく、ココアの文字列フォーマッタ%@を使用しないことに注意してください。私はprintfスタイルの書式コードを望むものを私は実際にやろうとしていることはコードで迅速かつ汚い表形式のアライメントを取得しているので、 %-10sのような。)2.2スウィフト

この質問の懸念。

+0

興味深い。型を 's'の注釈に' String'とするとどうなりますか? – Alexander

答えて

1

だけで位置合わせのためのC文字列を作成しないでください。それには方法stringByPaddingToLengthがあります。

// Swift 2 
s.stringByPaddingToLength(10, withString: " ", startingAtIndex: 0) 

// Swift 3 
s.padding(toLength: 10, withPad: " ", startingAt: 0) 

文字列が10 UTF-16コード単位より長い場合は、文字列が切り捨てられます。

文字列の延長として、NSStringの

  • func cStringUsingEncoding(encoding: NSStringEncoding) -> [CChar]?の方法として、

    1. func cStringUsingEncoding(encoding: UInt) -> UnsafePointer<Int8>:ここ


      の問題は、スウィフトにある2つの方法がcStringUsingEncodingという名前がありますポインタが必要な場合は、文字列ではなくNSStringを使用する必要があります。

      最初の例では、リテラル文字列は、文字列またはNSStringのことができるので、他の一つは動作しないので、コンパイラは、NSStringのを選択します。

      ただし、2番目の例では、sの型は既にStringに設定されているため、[CChar]?を返すメソッドが選択されています。

      これは、NSStringのようにsを強制することによって、周りに加工することができます

      let s: NSString = "hello world" 
      String(format:"%s", s.cStringUsingEncoding(NSUTF8StringEncoding)) 
      
  • 0

    kennytmの答えは明らかに最良の方法です。

    しかし、まだそれを間違った方法を行うには、NSStringのを経由せずスウィフト文字列に基づいて交流文字列へのアクセスを取得する方法について疑問に思っている誰のために、これはまた、(スウィフト2.2)動作するようです:

    var s:String = "dynamic string" 
    s.nulTerminatedUTF8.withUnsafeBufferPointer { (buffptr) -> String in 
        let retval:String = String(format:"%s",buffptr.baseAddress) 
        return retval 
    } 
    
    +1

    Simpler: 's.withCString {...}'を使います。 –

    +0

    はい、はるかに良いです。 – algal

    関連する問題