C char array to swift string

swift 4.2.
in my swift code , i return char array as part of a structure from a c function. The print statement on the c side is proper. on c side "abcd.." shows up as "97,98,99, ...: in the swift side. And it
prints the entire 16 byte array instead just of the 5 bytes. on the C side , it print only 5 bytes as it should.

If I understand your problem correctly, you should be able to use the String.init(cString:) initialiser to create a swift string from the c char array you have.

I think i tried this and gave me compile error that i thought I could not resolve it for some reason. if you have a bit more code around it, it helps. I try this again more attentively.

I suspect that you’re dealing with a fixed-size array in C, which is imported into Swift as a tuple. This is quite tricky to work with. For my general advice on the subject, see this DevForums post. In this specific case, you probably want to adapt my second snippet to call String.init(cString:) on the start pointer. For example, if you wanted to make a string from the f_fstypename property in an statfs structure, you’d write:

extension statfs {
    var fstypename: String {
        return withUnsafePointer(to: self.f_fstypename) { tuplePtr in
            let start = tuplePtr.qpointer(to: \.0)!
            return String(cString: start)
        }
    }
}

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

4 Likes

What swift type is the c char array that you have?

used the approach almost like in below from this site:

var record = mystruct
let name = withUnsafePointer(to: &record.name) {
    $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout.size(ofValue: $0)) {
        String(cString: $0)
    }
}
seems to work.
is this OK?.
2 Likes

Thank you for this, extremely educating, The Peril of the Ampersand.

I now finally understand why the following note says what it says :joy:

Important

The pointer created through implicit bridging of an instance or of an array’s elements is only valid during the execution of the called function. Escaping the pointer to use after the execution of the function is undefined behavior. In particular, do not use implicit bridging when calling an UnsafeMutablePointer initializer.

var number = 5
let numberPointer = UnsafeMutablePointer<Int>(&number)// Accessing 'numberPointer' is undefined behavior.
1 Like