views:

1846

answers:

3

I have an Cocoa app that calls a web service. When I parse the response from the web service I am getting a \n as the last character in my foundCharacters delegate for the NSXMLParser for each element in the XML.

When I try to do the following:

if (![string isEqualToString:@"\n"])

The check will always fails to catch the newline. Anyone know a good way to string check a newline?

I also find it odd that each element would have a newline at the end of each value, even though I see no evidence of that in the output from the web service.

This is quite the problem for something that should be exceptionally easy to do.

+11  A: 

I think this is just what you need?
text = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

phunehehe
Worked like a charm. Just out of curiosity, anyone know why this must be done? In almost every other language you wouldn't need to do this step, you could simply do a string comparison on a newline, or it an issue of how UNIX interprets the linefeed carriage return like jayw mentioned?
Scott Lance
Scott Lance: Read my answer. It explains why his `isEqualToString:` message didn't work as he expected.
Peter Hosey
+7  A: 

When I parse the response from the web service I am getting a \n as the last character …

When I try to do the following:

if (![string isEqualToString:@"\n"])

The check will always fails to catch the newline.

That message will only return YES if string is one character long and that character is \n.

If you want to test whether a string ends with \n, then you need to use hasSuffix::

if (![string hasSuffix:@"\n"])

If you want to strip \n from the end of the string and use what remains, phunehehe's solution is the correct one.

Edit: In jayw's answer, he points out the web service may be giving you CRLF-terminated text. This is a valid point, and you should not only look for \n at the end the line, but also check for a full \r\n sequence. The code he presents is one way to do that. However you do it, you still need to delete the full line separator, even if it's a \r\n sequence.

Peter Hosey
+2  A: 

The web service is likely terminating all lines with CRLF, i.e., "\r\n". You're on a UNIX system, so the linefeed character '\n' is taken as the line separator; the carriage return '\r' is left as part of the previous line. When printed, it will have the same effect as '\n'. Have you verified (using, say, strvis) that the line-final character is '\n' and not '\r'?

-[NSString hasSuffix:] will only catch the specific newline character you provide. To test if the string ends in a newline or whitespace, here is a putative category method:

- (BOOL)my_hasWhitespaceOrNewlineSuffix {
  NSRange r = [self rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]
                                    options:NSBackwardsSearch];
  BOOL foundChar = r.location != NSNotFound;
  BOOL isLineFinal = foundChar && (r.location + r.length == [self length]);
  return isLineFinal;
}

You can use phunehehe's suggestion of text = [text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] to remove any line-final whitespace or newlines.

Jeremy W. Sherman