Skip to content

Instantly share code, notes, and snippets.

@yossan
Last active May 20, 2022 12:47
Show Gist options
  • Save yossan/51019a1af9514831f50bb196b7180107 to your computer and use it in GitHub Desktop.
Save yossan/51019a1af9514831f50bb196b7180107 to your computer and use it in GitHub Desktop.
Making UnsafeMutablePointer<Int8> from String
// Method 1
// String → UnsafePointer<Int8> → UnsafeMutablePointer<Int8>
// Note: func withCString<Result>(_ body: (UnsafePointer<Int8>) throws -> Result) rethrows -> Result
// Note: String.UTF8View doesn't include null character.
func makeCString(from str: String) -> UnsafeMutablePointer<Int8> {
let count = str.utf8.count + 1
let result = UnsafeMutablePointer<Int8>.allocate(capacity: count)
str.withCString { (baseAddress) in
// func initialize(from: UnsafePointer<Pointee>, count: Int)
result.initialize(from: baseAddress, count: count)
}
return result
}
//MARK: -- EXAMPLES
do {
let str = "おはよう World さん 🌄 Now sun has been rising!"
let cstr = makeCString(from: str)
let restr = String(cString: cstr)
print(str == restr) // true
let str2 = "✑ 🍍 🍎 ✒"
let cstr2 = makeCString(from: str2)
let restr2 = String(cString: cstr2)
print(str2 == restr2) // true
}
// Method 2
// UnsafeMutableBufferPointer<Int8> → UnsafeMutablePointer<Int8>
// Note: var utf8CString: ContiguousArray<CChar> { get }
// Note: utf8CString includes the null character (a.k.a null terminator) .
// Note: CChar = Int8
func makeCString2(from str: String) -> UnsafeMutablePointer<Int8> {
let count = str.utf8CString.count
let result: UnsafeMutableBufferPointer<Int8> = UnsafeMutableBufferPointer<Int8>.allocate(capacity: count)
// func initialize<S>(from: S) -> (S.Iterator, UnsafeMutableBufferPointer<Element>.Index)
_ = result.initialize(from: str.utf8CString)
return result.baseAddress!
}
//MARK: -- EXAMPLE
do {
let str = "おはよう World さん 🌄 Now sun has been rising!"
let cstr = makeCString2(from: str)
let restr = String(cString: cstr)
print(str == restr) // true
let str2 = "✑ 🍍 🍎 ✒"
let cstr2 = makeCString2(from: str2)
let restr2 = String(cString: cstr2)
print(str2 == restr2) // true
}
@nikolay-kapustin
Copy link

let str = "some str"
let cStr = from.cString(using: .ascii)
// in fact, cStr the same as UnsafeMutablePointer

@yossan
Copy link
Author

yossan commented Sep 11, 2020

Thanks for your reply.

cString(using:) method is an Foundation extension, originally a method of NSString.
https://developer.apple.com/documentation/foundation/nsstring/1408489-cstring

Therefore it need to import Foundation.

Copy link

ghost commented Jan 11, 2021

Awesome! That's really help me a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment