how to get rid of the compiler warning in XCode 5.1
in Stringtable is of course a string with a format specifier (updated: now in front of code)
"fmtDetail" = "Count: %d";
int number = 0;
//Compiler warning: Data argument not used by format string
NSString *text = [NSString stringWithFormat:NSLocalizedString(#"fmtDetail", nil), number];
//this gets no warning
NSString *fmtDetail = NSLocalizedString(#"fmtDetail", nil);
NSString *text2 = [NSString stringWithFormat:fmtDetail, number];
It is not the compiler warning that is poor - you should correct your code.
There seems to be an %d (or similar) missing in the #"fmDetail".
Or you should get rid of the number argument - that is not used.
Depends on what you are actually trying to do...
NSString *text = [NSString stringWithFormat:NSLocalizedString(#"fmtDetail%d", nil), number];
NSString *text = [NSString stringWithFormat:NSLocalizedString(#"fmtDetail %d", nil), number];
NSString *text = [NSString stringWithString:NSLocalizedString(#"fmtDetail", nil)];
Second note: this #"fmtDetail%d" should match the key in the plist dictionary (translated strings). It could also be simly #"theDeatils" - the string that returned from your plist is the one that should actually hold formatting data for the string.
Why would one want to use the %d in the key? Because NSLocalizedString returns the key as the result if it doesn't find string with appropriate key.
EDIT: MartinR found the real reason for why this warning appears. Just a note that might be useful: since localizing strings usually means translation into many languages (duh) you might need to use numbered placeholders - not all languages share the same basic sentence structure.
This seems to be not a bug, but a new feature of the compiler that comes with Xcode 5.1 (beta). It expects now that in
[NSString stringWithFormat:NSLocalizedString(key, ...), arguments... ]
the key itself is a valid format for the given arguments.
(In other words, the key uses the same format specifiers as its value from the strings file).
For example:
// Source code:
[NSString stringWithFormat:NSLocalizedString(#"Count = %d", nil), number]
// Localizable.strings:
"Count = %d" = "Die Anzahl ist %d";
This is an advantage because the compiler can now check that the number and types
of the format specifiers match the actual arguments even with localizable format
strings. That was not possible before (as far as I know).
For example, this will cause a warning in Xcode 5.1 beta, but not in Xcode 5.0.2:
[NSString stringWithFormat:NSLocalizedString(#"fmtDetail %f", nil), 13];
// warning: format specifies type 'double' but the argument has type 'int' [-Wformat]
(And as #rokjarc already had pointed out, using a valid format string as key makes
sense anyway, because NSLocalizedString() returns the key if no matching string
is found in the Localizable.strings file.)
Related
i have star micronics and im implementing SDK in my app, but i cant print the € symbol
[mutableData appendData:[#"\x1b\x1d\x74\x04 123" dataUsingEncoding:NSMacOSRomanStringEncoding allowLossyConversion:YES]];
but print other character
also try with
[mutableData appendData:[#"\xE2\x82\xac\r\n 123" dataUsingEncoding: NSUTF8StringEncoding allowLossyConversion:YES]];
someone knows what is the code to print it?
This will do the trick:
builder is your ISCBBuilder variable.
builder.append(.CP858)
builder.appendByte(0xd5)
NSString in Objective-C is internally encoded as UTF-16, and the euro symbol has code 0x20AC. So first you need to define your string like so:
NSString *euroSymbol1 = #"\u20AC";
NSString *euroSymbol2 = #"€"; // same as euroSymbol1
if ([euroSymbol1 isEqualToString:euroSymbol2])
NSLog(#"equivalent"); // this is printed
NSString *price = [NSString stringWithFormat:#"%# %.2f", euroSymbol1, 123.45];
NSLog(#"%#", price); // prints: "€ 123.45"
Note that if you just write "€" the compiler is smart to re-encode your source code encoding to the NSString encoding, so it is trivial to read.
Then you need to understand what encoding does your printer support. If it supports Unicode, you should try it first, because it definitely contains the euro symbol. Note that the whole mutableData must be in the same encoding, so if you have appended other strings before this one, you need to make sure that all of them use the same encoding (for example NSUTF8StringEncoding).
If you need to use NSMacOSRomanStringEncoding, then the euro symbol might not be supported (see this reply), although here in the table you can still see it under the code 219.
Consider below code:
int count = 1;
NSString* format = count == 1 ? #"One %2$#" : #"%1$d %2$#s";
NSString* result = [NSString stringWithFormat: format, count, #"Bread"];
What count is not 1, the result is valid:
2 Breads
4 Breads
However the count is 1, then it causes EXC_BAD_ACCESS
NSLog(#"%#", [NSString stringWithFormat:#"One %2$#", 1, #"Bread"]);
Xcode compiler complains with upper code:
Data argument not used by format string
I know the reason for this error.
However My approach(Dynamic format that may skips some data) is also useful what if it works.
Is there any workaround for this?
[NSString stringWithFormat:] does not support positional parameters.
That looks like a bug in [NSString stringWithFormat:].
One workaround (hack) would be to use plain printf functions and convert the result to
NSString:
char *format = count == 1 ? "One %2$s" : "%1$d %2$ss";
char *tmp;
asprintf(&tmp, format, count, "Bread");
NSString *result = [NSString stringWithUTF8String:tmp];
free(tmp);
But the proper solution would be to create a "Localizable.strings" file with
language plural rules, as described in
"Handling Noun Plurals and Units of Measurement"
in the Internationalization and Localization Guide.
See also "String Localization"
for documentation and examples.
Replace :-
NSLog(#"%#", [NSString stringWithFormat:#"One %2$#", 1, #"Bread"]);
with Modified below:-
NSLog(#"%#", [NSString stringWithFormat:#"%#,%d,%#",#"One %2$#", 1, #"Bread"]);
I have the following code and I'm banging my head against a wall trying to figure out what's producing the errors.
NSMutableString *entry = (#"%# (%#): %#",translatedHeadword,adlerNumber,meaning);
entry = [entry replaceOccurrencesOfString:#"<br/>" withString:#" " options:NSCaseInsensitiveSearch range:NSMakeRange(0, entry.length)];
The second line is giving two errors: Implicit conversion of 'NSUInteger' toNSMutableStringis disallowed with ARC and Incompatible integer to pointer conversion assigning to NSMutableString from NSUInteger. But translatedHeadword, adlerNumber, and meaning are all NSStrings. adlerNumber contains characters representing numbers, but it's still a string.
What am I doing wrong?
The syntax (#"%#", foo) does not produce string formatting. You need to use [NSMutableString stringWithFormat:] to do string formatting.
Also, replaceOccurrencesOfString:... returns the number of changed things and mutates the string itself. So, it's complaining about the assignment entry = ... because the right-hand side is the NSUInteger returned by replaceOccurencesOfString:....
I've got some trouble to retrieve some text message from my server, especially with the encoding. Messages can be from many languages (so they can have accents, be in japanese,... ) and can include emoji.
I'm retrieving my message with a JSON with some info. Here is some logs example :
(lldb) po dataMessages
<__NSCFArray 0x14ecc7f0>(
{
author = "User 1";
text = "Hier, c'\U00c3\U00a9tait incroyable";
},
{
...
}
)
(lldb) po [[dataMessages objectAtIndex:0] objectForKey:#"text"]
Hier, c'était incroyable
I'm able to get the correct text with :
const char *c = [[[dataMessages objectAtIndex:indexPath.row] objectForKey:#"text"] cStringUsingEncoding:NSWindowsCP1252StringEncoding];
NSString *myMessage = [NSString stringWithCString:c encoding:NSUTF8StringEncoding];
However, if the message contains emoji, cStringUsingEncoding: return a NULL value.
I don't have control on my server, so I can't change their encoding before messages are sent to me.
The problem is determining the encoding correctly. Emoji are not part of NSWindowsCP1252StringEncoding so the conversion just fails.
Moreover, you are passing through an unnecessary stage. Do not make an intermediate C string! Just call NSString's initWithData:encoding:.
In your case, calling NSWindowsCP1252StringEncoding was always a mistake; I'm surprised that this worked for any string. C3A9 is Unicode (UTF8). So just call initWithData:encoding: with the UTF8 encoding (NSUTF8StringEncoding) from the get-go and all will be well.
I thought I had nailed converting an int to and NSString a while back, but each time I run my code, the program gets to the following lines and crashes. Can anyone see what I'm doing wrong?
NSString *rssiString = (int)self.selectedBeacon.rssi;
UnitySendMessage("Foo", "RSSIValue", [rssiString UTF8String] );
These lines should take the rssi value (Which is an NSInt) convert it to a string, then pass it to my unity object in a format it can read.
What am I doing wrong?
NSString *rssiString = [NSString stringWithFormat:#"%d", self.selectedBeacon.rssi];
UPDATE: it is important to remember there is no such thing as NSInt. In my snippet I assumed that you meant NSInteger.
If you use 32-bit environment, use this
NSString *rssiString = [NSString stringWithFormat:#"%d", self.selectedBeacon.rssi];
But you cann't use this in 64-bit environment, Because it will give below warning.
Values of type 'NSInteger' should not be used as format arguments; add
an explicit cast to 'long'
So use below code, But below will give warning in 32-bit environment.
NSString *rssiString = [NSString stringWithFormat:#"%ld", self.selectedBeacon.rssi];
If you want to code for both(32-bit & 64-bit) in one line, use below code. Just casting.
NSString *rssiString = [NSString stringWithFormat:#"%ld", (long)self.selectedBeacon.rssi];
I'd like to provide a sweet way to do this job:
//For any numbers.
int iValue;
NSString *sValue = [#(iValue) stringValue];
//Even more concise!
NSString *sValue = #(iValue).stringValue;
NSString *rssiString = [self.selectedBeacon.rssi stringValue];
For simple conversions of basic number values, you can use a technique called casting. A cast forces a value to perform a conversion based on strict rules established for the C language. Most of the rules dictate how conversions between numeric types (e.g., long and short versions of int and float types) are to behave during such conversions.
Specify a cast by placing the desired output data type in parentheses before the original value. For example, the following changes an int to a float:
float myValueAsFloat = (float)myValueAsInt;
One of the rules that could impact you is that when a float or double is cast to an int, the numbers to the right of the decimal (and the decimal) are stripped off. No rounding occurs. You can see how casting works for yourself in Workbench by modifying the runMyCode: method as follows:
- (IBAction)runMyCode:(id)sender {
double a = 12345.6789;
int b = (int)a;
float c = (float)b;
NSLog(#"\ndouble = %f\nint of double = %d\nfloat of int = %f", a, b, c);
}
the console reveals the following log result:
double = 12345.678900
int of double = 12345
float of int = 12345.000000
original link is http://answers.oreilly.com/topic/2508-how-to-convert-objective-c-data-types-within-ios-4-sdk/
If self.selectedBeacon.rssi is an int, and it appears you're interested in providing a char * string to the UnitySendMessage API, you could skip the trip through NSString:
char rssiString[19];
sprintf(rssiString, "%d", self.selectedBeacon.rssi);
UnitySendMessage("Foo", "RSSIValue", rssiString );