Skip to content

Instantly share code, notes, and snippets.

@algal
Last active February 8, 2023 16:14
Show Gist options
  • Select an option

  • Save algal/23b10062a558aec7679e4c854096f88e to your computer and use it in GitHub Desktop.

Select an option

Save algal/23b10062a558aec7679e4c854096f88e to your computer and use it in GitHub Desktop.
Read a file one line at a time in Swift
import Darwin
/**
Returns a lazy sequence that returns a String for every line of `file`.
Example 1:
// print all lines from a file
let file = fopen(NSBundle.mainBundle().pathForResource("Cartfile", ofType: nil)!,"r")
for line in lineGenerator(file) { print(line,separator: "", terminator: "") }
fclose(file)
Example 2:
// echo lines from stdin
for line in lineGenerator(stdin) { print(line, separator: "", terminator: "") }
*/
func lineGenerator(file:UnsafeMutablePointer<FILE>) -> AnyGenerator<String>
{
return AnyGenerator { () -> String? in
var line:UnsafeMutablePointer<CChar> = nil
var linecap:Int = 0
defer { free(line) }
return getline(&line, &linecap, file) > 0 ? String.fromCString(line) : nil
}
}
let p = "/path/to/file" // could be returned by NSBundle.pathForResource, if we were using Foundation
let f = fopen(p,"r")
let g = lineGenerator(f)
for line in g {
// suppress print's automatic line ending, since
// lineGenerator captures every line's own new line character.
print(line, separator: "", terminator: "")
}
@cham-s
Copy link
Copy Markdown

cham-s commented Aug 4, 2017

Your snippet made me learn more about Sequence and how to define a custom one.
Thanks!

@AlexandrGraschenkov
Copy link
Copy Markdown

Wrapped your code inside swift class in this gist

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