I am trying to understand how Swift 3 File I/O works in a linux environment. I put together a trivial test program using what I
can glean from the few examples I can find. See below.
===============================
import Glibc
import Foundation
let filename = Process.arguments[1]
let file_handle = fopen (filename, "r")
let BUFSIZE = 1024
var buf = [CChar](repeating:CChar(0), count:BUFSIZE)
while fgets(&buf, Int32(BUFSIZE), file_handle) != nil
{
print(buf)
}
exit(0)
The program runs, but produces a stream of integer arrays, each of 1024 bytes. I can see what appears to be ASCII character values in the sample text, plus a lot of trailing zeros. I suspect I haven't mapped the bytes in buf to Strings, so how should that be done?
--
Ken Burgett
Principal Software Engineer
Email: kenb@iotone.io
Office: 530.693.4449
Mobile: 831.332.6846
URL: www.iotone.co
`fgets` sets up `buf` to hold a C string, so you have to convert it to a Swift string. How do you do this depends on the encoding of the bytes. If you expect the C string to be UTF-8, then `String(validatingUTF8:)` is the way to go.
IMPORTANT: This conversion can fail, which is why the above will print a bunch of optional strings, and you will have to decide what to your program should do when it does.
* * *
btw This question came up recently. See the thread for other suggestions about how to handle it.
Sorry, that does not compile with Swift 3. First of all, the expression "(count:BUFSIZE, repeatedValue:CChar(0))" must be written as "(repeating:CChar(0), count:BUFSIZE)", Note that the order within the expression is significant (don't ask me why, it just is. Ask the language designers).
Second, print line causes the compiler to disgorge the following:
" error: 'fromCString' is unavailable: Please use String.init?(validatingUTF8:) instead. Note that it no longer accepts NULL as a valid input. Also consider using String(cString:), that will attempt to repair ill-formed code units.
print(String.fromCString(buf)!, terminator:"")
^~~~~~~~~~~
Swift.String:4:24: note: 'fromCString' has been explicitly marked unavailable here
public static func fromCString(_ cs: UnsafePointer<CChar>) -> String?
"
I frankly don't know how to parse that compiler output, since it is NOT like Swift 2.2, and is apparently trying to explain that in some tortured form of syntax. I don't know how to map that response into working code.
···
On 2016-05-28 18:54, TUNG CK wrote:
Same as Linux 2.2
import Glibc
let path = "./sample.txt"
let BUFSIZE = 1024
let fp = fopen(path, "r")
if fp != nil {
var buf = [CChar](count:BUFSIZE, repeatedValue:CChar(0))
while fgets(&buf, Int32(BUFSIZE), fp) != nil {
print(String.fromCString(buf)!, terminator:"")
}
}
Ken Burgett via swift-users <swift-users@swift.org> 於 29 May 2016 2:05 AM 寫道:
Hi all,
I am trying to understand how Swift 3 File I/O works in a linux environment. I put together a trivial test program using what I
can glean from the few examples I can find. See below.
===============================
import Glibc
import Foundation
let filename = Process.arguments[1]
let file_handle = fopen (filename, "r")
let BUFSIZE = 1024
var buf = [CChar](repeating:CChar(0), count:BUFSIZE)
while fgets(&buf, Int32(BUFSIZE), file_handle) != nil
{
print(buf)
}
exit(0)
The program runs, but produces a stream of integer arrays, each of 1024 bytes. I can see what appears to be ASCII character values in the sample text, plus a lot of trailing zeros. I suspect I haven't mapped the bytes in buf to Strings, so how should that be done?
--
Ken Burgett
Principal Software Engineer
Email: kenb@iotone.io
Office: 530.693.4449
Mobile: 831.332.6846
URL: www.iotone.co
<main.swift>
_______________________________________________
swift-users mailing list
swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users
--
Ken Burgett
Principal Software Engineer
Email: kenb@iotone.io
Office: 530.693.4449
Mobile: 831.332.6846
URL: www.iotone.co