Carriage-return New-Line (aka linefeed)

Perhaps this will save someone else from deciding that they've lost their mind.


I receive String data from hardware. I get several "lines" of data at a time, separated by carriage-return characters (0x0d) -> "\r".

I split the data into "words" with code like:

let splitChars = "\r " // carriage-return and space

words = incoming.split() { splitChars.contains($0) }


Then I encoutered hardware that was sending carriage-return and new-line to end each line (0x0d0a) -> "\r\n" which of course my code didn't handle. So I change it to

let splitChars = "\r \n"

and it didn't work. I tried lots of combinations. Finally I settled on

let splitChars = "\r\n "

and that did work... unless they weren't sendng the new-lines... then I was broke again.


So here's the facts:
In a String, "\r\n" is ONE character.

It matches only the "character" that is "\r\n".

It does NOT match "\r" or "\n". If you want to match both types of input, you need:

let splitChars = "\r\n \r"

If you need to match new-line by itself also, you can do: let splitChars = "\r\n \n\r"

because "\n\r" is TWO characters, not one.

My sanity is restored (sorta).

Barry

hi,


i ran across a similar problem a while ago, where some of the data were coming across as "\r\n", and it was a pain to work with (the data came out of Numbers as a tab-separated file, i think).


and your comment about treating "\r\n" as a single character is somewhat what i remember to be the issue.


so before splitting lines by "\r", i did the following to remove all the "\n"


fileContents = fileContents.replacingOccurrences(of: "\n", with: "")


splitting on "\r" seemed to work OK after that.


not sure if that's exactly what's the issue here ...


hope that helps as well,

DMG

Thanks for the comment. "fileContents" must not have been String at that point because "\n" wouldn't have been found if it was, in fact, "\r\n" (since that is a single character and not a combination including \n).

hi,


"fileContents" was in fact of type String. apologies for not making that clear. the expanded code section i used back then was:


  var fileContents: String
    do {
      fileContents = try String(contentsOfFile: filePath, encoding: String.Encoding.utf8)
    } catch let error {
      print("Error reading file: \(error.localizedDescription)")
      return nil
    }
  fileContents = fileContents.replacingOccurrences(of: "\n", with: "")
  let records = fileContents.split(separator: "\r").map() { String($0) }


i'm sorry, it's been a while -- but i do remember this solving my particular problem at the time and being surprised that it worked.


hope this helps moving forward,

DMG

Thank you, Barry and DMG for this input. It has literally been driven me nuts :) Helped a lot!

Carriage-return New-Line (aka linefeed)
 
 
Q