21

I am trying to use dispatch_queue_create with a dynamic String that I am creating at runtime as the first parameter. The compiler complains because it expects a standard c string. If I switch this to a compile time defined string the error goes away. Can anyone tell me how to convert a String to a standard c string?

phoganuci
  • 4,984
  • 9
  • 39
  • 50

6 Answers6

32

You can get a CString as follows:

import Foundation

var str = "Hello, World"

var cstr = str.bridgeToObjectiveC().UTF8String

EDIT: Beta 5 Update - bridgeToObjectiveC() no longer exists (thanks @Sam):

var cstr = (str as NSString).UTF8String
Cezary Wojcik
  • 21,745
  • 6
  • 36
  • 36
  • 5
    bridgeToObjectiveC is gone in beta 5 - you now need to use `(str as NSString).UTF8String` – Sam Aug 05 '14 at 12:23
  • Note that this solution is also required if you want to use %s formatting in your String(format:,args:...) formatter. The docs suggest that you shouldn't use %s, but of course sometimes you have to (for example, inserting a string value into a localized error message). So: `String("Player %s not found", player.name)` will give you garbage (because player.name is a Swift String object, not a null-terminated string) but `String("Player %s not found", (player.name as NSString).UTF8String)` will produce goodness. – Opus1217 Dec 28 '15 at 14:59
15

There is also String.withCString() which might be more appropriate, depending on your use case. Sample:

var buf = in_addr()
let s   = "17.172.224.47"
s.withCString { cs in inet_pton(AF_INET, cs, &buf) }

Update Swift 2.2: Swift 2.2 automagically bridges String's to C strings, so the above sample is now a simple:

var buf = in_addr()
let s   = "17.172.224.47"
net_pton(AF_INET, s, &buf)

Much easier ;->

hnh
  • 13,957
  • 6
  • 30
  • 40
9

Swift bridges String and NSString. I believe this may be possible alternative to Cezary's answer:

import Foundation

var str = "Hello World"

var cstr = str.cStringUsingEncoding(NSUTF8StringEncoding)

The API documentation:

/* Methods to convert NSString to a NULL-terminated cString using the specified
   encoding. Note, these are the "new" cString methods, and are not deprecated 
   like the older cString methods which do not take encoding arguments.
*/
func cStringUsingEncoding(encoding: UInt) -> CString // "Autoreleased"; NULL return if encoding conversion not possible; for performance reasons, lifetime of this should not be considered longer than the lifetime of the receiving string (if the receiver string is freed, this might go invalid then, before the end of the autorelease scope)
mbeaty
  • 1,549
  • 1
  • 11
  • 8
  • This gives back a standard cstring, I was looking for the Swift CString struct. Thanks for the input, though! – phoganuci Jun 08 '14 at 07:41
  • As you can see, the function returns a CString struct (-> CString). Please explain. – mbeaty Jun 08 '14 at 08:35
  • My apologies. You are correct. It turns out I needed the exact opposite of what I asked, just a plain old vanilla c string. Sorry about the confusion, your answer was correct as asked. I gave an upvote for answering the question as originally posed. – phoganuci Jun 08 '14 at 15:20
  • So, the answer that has been accepted is not what you need either. – mbeaty Jun 08 '14 at 19:02
7

Swift 3 version as @mbeaty's say:

import Foundation

var str = "Hello World"

var cstr = str.cString(using: String.Encoding.utf8)

Apple API:

Foundation > String > cString(using:)

Instance Method

cString(using:)

Returns a representation of the String as a C string using a given encoding.

Community
  • 1
  • 1
Leo
  • 1,545
  • 13
  • 24
0

Swift 5

var cstr = (userStr as NSString).utf8String

0

Swift 5

Remember to guarantee the lifetime, like:

let myVariable: String = "some text...";
withExtendedLifetime(myVariable) {
    myVariable.utf8CString.withUnsafeBufferPointer { buffer in
        let result = buffer.baseAddress!;

        // ... Do something with result
    }
}
Top-Master
  • 7,611
  • 5
  • 39
  • 71