Outputting Formatted NSString - objective-c

UIAlertView *message = [[UIAlertView alloc] initWithTitle:[[LanguageManager sharedLanguageManager] get:#"Notice"]
message:[NSString stringWithFormat:[[LanguageManager sharedLanguageManager] get:#"Notice_Text"]]
delegate:nil
cancelButtonTitle:[[LanguageManager sharedLanguageManager] get:#"Close"]
otherButtonTitles:nil];
Hi, let me explain my codes above. Basically it calls up an UIAlertView with data read from a .plist via my LanguageManager singleton class. The LanguageManager get function basically returns a NSString*. I know I should use the NSLocalizedString class but I had been using this class for a while now, so I had decided to stick to it.
My problem lies with the "message:" parameter. The string I am trying to read contains formatting characters like \n but it does not output correctly and appears as \n instead of a line break when printed. I also get the "Format string is not a string literal" warning. Other parts of the app using similar method to return a string which contains %d or %f works correctly though, just the '\n' character not working.
Does anyone have any idea how I may overcome this?

"\n" is not a "formatting character": the compiler translates it to the appropiate code; the string NEVER contains the "\" and "n" characters.
Thus, if you string comes from a source that is NOT compiled by a (Objective-)C(++) compiler, "\n" will be just the two characters. Nothing will turn them into a newline, unless you do it yourself with something like
NewString=[MyString stringByReplacingOccurrencesOfString:#"\\n" withString:#"\n"];
Note the two different strings: in the first case, "\" prevents the compiler from doing the \n -> newline conversion, while the second string will be an actual newline.
The warning about a non-literal format string is somewhat pointless; I've yet to find a good way to get rid of that one (for now, I just disable it entirely, using -Wno-format-nonliteral on clang++ >= 4.0).

Related

Parsing file with percent signs (%) in Objective-C

I'm writing a parser for fortune files. Fortune is a small app on *nix platforms that just prints out a random "fortune". The fortune files are straight text, with each fortune being separated by a percent sign on its own line. For example:
A little suffering is good for the soul.
-- Kirk, "The Corbomite Maneuver", stardate 1514.0
%
A man either lives life as it happens to him, meets it head-on and
licks it, or he turns his back on it and starts to wither away.
-- Dr. Boyce, "The Menagerie" ("The Cage"), star date unknown
%
What I've found is that when parsing the file, stringWithContentsOfFile returns a string with the % signs in place. For example:
#"A little suffering is good for the soul.\n\t\t-- Kirk, \"The Corbomite Maneuver\", stardate 1514.0\n%\nA man either lives life as it happens to him, meets it head-on and\nlicks it, or he turns his back on it and starts to wither away.\n\t\t-- Dr. Boyce, \"The Menagerie\" (\"The Cage\"), stardate unknown\n%"
However, when I call componentsSeparatedByCharactersInSet on the file contents, everything is parsed as a string, with the exception of the percent signs, which are NSTaggedPointerString. When I print out the lines, the percent signs are gone.
Is this because the percent sign is a format specifier for strings? I would think in that case that the initial content pull would escape those.
Here's the code:
NSFileManager *fileManager;
fileManager = [NSFileManager defaultManager];
NSStringEncoding stringEncoding;
// NSString *fileContents = [NSString stringWithContentsOfFile:fileName encoding:NSASCIIStringEncoding error:nil];
NSString *fileContents = [NSString stringWithContentsOfFile:fileName usedEncoding:&stringEncoding error:nil];
NSArray *fileLines = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
The used encoding ends up being UTF-8. You can see I have also tried specifying plain ASCII, but it yields the same results.
So the question is, how do I retain the percent signs? Or, may I should use it as the separator character and then parse each of the subsequent results individually.
You are calling NSLog() but passing the line strings as the format string. Something like:
NSLog(lineString);
Therefore, any percent characters in the line strings are interpreted as format specifiers. You should (almost) never pass strings that come from outside sources — i.e. strings which are not hard-coded in your code — as format strings to any function (NSLog(), printf(), +[NSString stringWithFormat:], etc.). It's not safe and you'll sometimes get unexpected results like you've seen.
You should always log a single string like this:
NSLog(#"%#", lineString);
That is, you need to pass a hard-coded format string and use the foreign string as data for that to format.
NSTaggedPointerString is just subclass of NSString. You can use anywhere as NSString.
But in your string
#"A little suffering is good for the soul.\n\t\t-- Kirk, \"The Corbomite Maneuver\", stardate 1514.0\n%\nA man either lives life as it happens to him, meets it head-on and\nlicks it, or he turns his back on it and starts to wither away.\n\t\t-- Dr. Boyce, \"The Menagerie\" (\"The Cage\"), stardate unknown\n%"
sign % is not percent sign. in Objective-C percent sign is declared as double of % mark
#"%%"

Objc-DataFile-Unreadable Substring-Unknown to any encoding

I have a DataFile, built by subsidiairy Application. I need to locate some substring contained in the data file. They are identifiable by the character symbols delimiting them. For instance : *!substringqSxt .The substring will vary from a project to another so I need to locate the symbols delimiting them to read the following substring. I also printed the file to different encodings trying which one was used and matched the original data file. found it was MacOsRomanStringEncoding.
I use NSRange:rangOfStringto locate the delimiting symbols. Here is my code :
char *debutAudio ="jjbj";
char *finAudio ="qSxt";
NSString *debutAudioConverted = [[NSString alloc]
initWithCString: debutAudio
encoding:NSMacOSRomanStringEncoding];
NSString *finAudioConverted = [[NSString alloc]
initWithCString: finAudio
encoding:NSMacOSRomanStringEncoding];
NSRange debutaudioRange =[dataFileContent rangeOfString:debutAudioConverted];
NSRange finaudioRange =[dataFileContent rangeOfString:finAudioConverted];
NSLog(#"range is %#",NSStringFromRange(debutaudioRange));
NSLog(#"range is %#",NSStringFromRange(finaudioRange));
Both NSLog returns range is {9223372036854775807, 0}
so not locating the delimiting strings there.
And if I ask to look for other strings contained in the file like "Settings" the rangeOfString will return the proper location and length.
I thought the file may contain multiple encodings, and tried converting with initWithCStringto any possible encoding but nothing would do.
Also if I open the file in text edit and use the "Find" function, it will not locate the delimiting string, but will locate other words. My guts tell me its related. I dont know where to look for info. Could the file be protected, I am reading a copy of it though.
I have found the problem occuring here. The proper encoding is still MacOsRoman. The problem is the prefix string *debutAudio "jjbj"there is actually a tiny space , like a quarter space between each characters. I have tried every unicode spaces listed here :https://www.cs.tut.fi/~jkorpela/chars/spaces.html#adj
without any success. Now I will tried to find some half or quarter space under MacOsRoman see if that is working.

Cocoa Error 2048 on NSRegularExpression

I'm attempting to use NSRegularExpression to search for a string inside a pbxproj (Inside the .xcodeproj folder).
I'm searching for the compiler flags in the "Begin PBXBuildFile section" area
NSString* findFlagsRegex = #"([A-Z0-9]{24}\\s\\/\\*\\s[A-Za-z\\.\\s0-9]+\\*\\/\\s=\\s{isa\\s\\=\\s[A-Za-z]*;\\s?fileRef\\s\\=\\s[A-Z0-9]*\\s\\/\\*\\s[A-Za-z0-9\\s\\.]*\\*\\/;\\ssettings\\s\\=\\s{[A-Za-z0-9_\\s\\=\"-]*;\\s\\};\\s};)";
NSRegularExpression* expression3 = [NSRegularExpression regularExpressionWithPattern:findFlagsRegex options:kNilOptions error:&err];
NSLog(#"Error: %#",[err description]);
Error Domain=NSCocoaErrorDomain Code=2048 "The value “([A-Z0-9]{24}\s\/\*\s[A-Za-z\.\s0-9]+\*\/\s=\s{isa\s\=\s[A-Za-z]*;\s?fileRef\s\=\s[A-Z0-9]*\s\/\*\s[A-Za-z0-9\s\.]*\*\/;\ssettings\s\=\s{[A-Za-z0-9_\s\="-]*;\s\};\s};)” is invalid." UserInfo=0x61800026a7c0 {NSInvalidValue=([A-Z0-9]{24}\s\/\*\s[A-Za-z\.\s0-9]+\*\/\s=\s{isa\s\=\s[A-Za-z]*;\s?fileRef\s\=\s[A-Z0-9]*\s\/\*\s[A-Za-z0-9\s\.]*\*\/;\ssettings\s\=\s{[A-Za-z0-9_\s\="-]*;\s\};\s};)}
I copy:
([A-Z0-9]{24}\s\/\*\s[A-Za-z\.\s0-9]+\*\/\s=\s{isa\s\=\s[A-Za-z]*;\s?fileRef\s\=\s[A-Z0-9]*\s\/\*\s[A-Za-z0-9\s\.]*\*\/;\ssettings\s\=\s{[A-Za-z0-9_\s\="-]*;\s\};\s};)
The regular expression above works in RegexPal, directly copying it from the invalid value from the error message on the same test data... so I'm not sure what's wrong :/
Not sure if this will add anything, but this is a Mac App and not an iOS app.
Your pattern contains a lone literal }. I believe you meant to have two literal {s and two literal }s - this is a slightly modified version of the pattern you had in your question, with three more \\s inserted to escape the curly braces that are currently not escaped in your code.
NSString* findFlagsRegex = #"([A-Z0-9]{24}\\s\\/\\*\\s[A-Za-z\\.\\s0-9]+\\*\\/\\s=\\s\\{isa\\s\\=\\s[A-Za-z]*;\\s?fileRef\\s\\=\\s[A-Z0-9]*\\s\\/\\*\\s[A-Za-z0-9\\s\\.]*\\*\\/;\\ssettings\\s\\=\\s\\{[A-Za-z0-9_\\s\\=\"-]*;\\s\\};\\s\\};)";
I'm not sure whether the bug is with RegexPal, or if RegexPal depends on the copy of JS that your browser uses, or if the bug is with NSRegularExpressions, but either way, escaping a character which doesn't need to be escaped shouldn't cause any issues (or at least it's not my understanding of regular expressions that it should.)

objective c UTF8String not working with japanese

I would like to show the NSString below on my UILabel:
NSString *strValue=#"你好";
but i can not show it on my UILabel i get strange characters!
I use this code to show the text:
[NSString stringWithCString:[strValue UTF8String] encoding:NSUTF8StringEncoding];
I tried [NSString stringWithCString:[strValue cStringUsingEncoding:NSISOLatin1StringEncoding] encoding:NSUTF8StringEncoding] and it worked
but i can not show emoticons with cStringUsingEncoding:NSISOLatin1StringEncoding so i have to use UTF8String.
Any help appreciated.
Your source file is in UTF-8, but the compiler you are using thinks it's ISO-Latin 1. What you think is the string #"你好" is actually the string #"你好". But when you ask NSString* to give you this back as ISO-Latin 1, and treat it as UTF-8, you've reversed the process the compiler took and you end up with the original string.
One solution that you can use here is to tell your compiler what encoding your source file is in. There is a compiler flag (for GCC it's -finput-charset=UTF-8, not sure about clang) that will tell the compiler what encoding to use. Curiously, UTF-8 should be the default already, but perhaps you're overriding this with a locale.
A more portable solution is to use only ASCII in your source file. You can accomplish this by replacing the non-ASCII chars with a string escape using \u1234 or \U12345678. In your case, you'd use
NSString *strValue=#"\u4F60\u597D";
Of course, once you get your string constant to be correct, you can ditch the whole encoding stuff and just use strValue directly.

Strings file Xcode - Remove the first and last " + ;

I just started using strings file in my projects. Or well, i'm trying to.
I had an error for a few days, and finally figured out you actually have to make strings in the file with "" and end the lines with a ; - that was a bummer to figure out ;)
Anywhoo, now i'm trying to get it sorted out and separated into smaller strings. It's working like a charm, but i just can't seem to get rid of the "" and ; on each line of the string.
For instance, i have this in my strings file (i'm separating by comma):
"This is a string,This is another string,And a final one";
I am trying to get it into 3 different strings, and after having done it, it looks like this in my 3 strings objects:
"This is a string
This is another string
And a final one";
So i need to remove the " in string 1, and the " + ; in string 3.
I hope it made sense. I really can't seem to figure this one out, as i haven't really worked with sorting around in strings too much, and yet alone working with a strings file.
Thanks on advance.
This should do the trick if ALL strings have the " and "; at the beginning/end of the total string.
firstString = [firstString substringFromIndex:1];
lastString = [lastString substringToIndex:[lastString length] - 3];
If you want to remove all occurances of " and ; use this before splitting:
totalString = [totalString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
totalString = [totalString stringByReplacingOccurrencesOfString:#";" withString:#""];
Typically, you use a tool to generate the .strings file from your code. You don't have to construct it manually.
In your code, when you want to use a string that should be localizable, you typically use one of the NSLocalizableString... macros. Like so:
textField.stringValue = NSLocalizableString(#"Hello, World!", "Standard programming greeting");
To generate the Localizable.strings file, you use the genstrings tool to scan your code for uses of such macros (and a few other things). It produces .strings files in the proper format.
For more, see these Apple documents:
Resource Programming Guide: String Resources
Internationalization Programming Topics