java.text.DecimalFormat equivalent in Objective C - objective-c

In java, I have
String snumber = null;
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number); //'number' is of type 'long' passed to a function
//which has this code in it
I am not aware of the DecimalFormat operations in java and so finding it hard to write an equivalent Obj C code.
How can I achieve this? Any help would be appreciated.

For that particular case you can use some C-style magic inside Objective-C:
long number = 123;
int desiredLength = 10;
NSString *format = [NSString stringWithFormat:#"%%0%dd", desiredLength];
NSString *snumber = [NSString stringWithFormat:format, number];
Result is 0000000123.
Format here will be %010d.
10d means that you'll have 10 spots for number aligned to right.0 at the beginning causes that all "empty" spots will be filled with 0.
If number is shorter than desiredLength, it is formatted just as it is (without leading zeros).
Of course, above code is valid only when you want to have numbers with specified length with gaps filled by zeros.
For other scenarios you could e.g. write own custom class which would use appropriate printf/NSLog formats to produce strings formatted as you wish.
In Objective-C, instead of using DecimalFormat "masks", you have to live with string formats.

Related

Convert a string into a int

I need some help here, I am currently making a game, but I got stuck somewhere. So, what I want is, if a Labels text is higher then the other labels text, then something will happen, I typed If Label26.Text > Label24.Text Then Label33.Visible = True which seems not to work, please, I need some help here, thanks. And yes, the labels text is NUMBERS.
The Text property of a label is a string. As far as computers go, you can't do math (using comparison operators like > will not return the result you are expecting) with strings because they are just a sequence of characters.
Even if the string only contains a number, the computer still sees it as a sequence of characters and not a number ("5" is a string literal with the character 5 in it, while 5 is an integer that can be used in a mathematic expression).
As some of the other commenters mentioned, you need to cast the Text property to an Integer or Double (or some other numeric data type). To do so, you'd want to use Int32.Parse to change the strings to integers.
If Int32.Parse(Label26.Text) > Int32.Parse(Label24.Text) Then Label33.Visible = True
You can use the int.tryParse to check if the content of the variable is a number or not. The output of the TryParse is a boolean, see the example below:
int num1 = 0;
bool num1_ = false;
num1_ = int.TryParse(txt1.Text.ToString(), out num1);
if (num1_)
{
// Is a number/integer
//Do something
}
else
{
//Is a string
//Do something else
}

Regular Expression for validate price in decimal

I really unable to find any workaround for regular expression to input price in decimal.
This what I want:-
12345
12345.1
12345.12
12345.123
.123
0.123
I also want to restrict digits.
I really created one but not validating as assumed
^([0-9]{1,5}|([0-9]{1,5}\.([0-9]{1,3})))$
Also want to know how is above expression different from the one
^([0-9]{1,5}|([0-9].([0-9]{1,3})))$ thats working fine.
Anyone with good explanation.
"I am using NSRegularExpression - Objective C" if this helps to answer more precisely
- (IBAction)btnTapped {
NSRegularExpression * regex = [NSRegularExpression regularExpressionWithPattern:
#"^\\d{1,5}([.]\\d{1,3})?|[.]\\d{1,3}$" options:NSRegularExpressionCaseInsensitive error:&error];
if ([regex numberOfMatchesInString:txtInput.text options:0 range:NSMakeRange(0, [txtInput.text length])])
NSLog(#"Matched : %#",txtInput.text);
else
NSLog(#"Not Matched : %#",txtInput.text);
}
"I am doing it in a buttonTap method".
This simple one should suit your needs:
\d*[.]?\d+
"Digits (\d+) that can be preceded by a dot ([.]?), which can itself be preceded by digits (\d*)."
Since you're talking about prices, neither scientific notation nor negative numbers are necessary.
Just as a point of interest, here's the one I usually used, scientific notation and negative numbers included:
[-+]?\d*[.]?\d+(?:[eE][-+]?\d+)?
For the new requirements (cf. comments), you can't specify how many digits you want on the first regex I gave, since it's not the way it has been built.
This one should suit your needs better:
\d{1,5}([.]\d{1,3})?|[.]\d{1,3}
"Max 5 digits (\d{1,5}) possibly followed ((...)?) by a dot itself followed by max 3 digits ([.]\d{1,3}), or (|) simply a dot followed by max 3 digits ([.]\d{1,3})".
Let's do this per-partes:
Sign in the beginning: [+-]?
Fraction number: \.\d+
Possible combinations (after sign):
Number: \d+
Fraction without zero \.\d+
And number with fraction: \d+\.\d+
So to join it all together <sign>(number|fraction without zero|number with fraction):
^[+-]?(\d+|\.\d+|\d+\.\d+)$
If you're not restricting the lengths to 5 digits before the decimal and 3 digits after then you could use this:
^[+-]?(?:[0-9]*\.[0-9]|[0-9]+)$
If you are restricting it to 5 before and 3 after max then you'd need something like this:
^[+-]?(?:[0-9]{0,5}\.[0-9]{1,3}|[0-9]{1,5})$
As far as the difference between your regexes goes, the first one limits the length of the number of digits before the decimal marker to 1-5 with and without decimals present. The second one only allows a single digit in front of the decimal pointer and 1-5 digits if there is no decimal.
How about this: ^([+-])?(\d+)?([.,])?(\d+)?$
string input = "bla";
if (!string.IsNullOrWhiteSpace(input))
{
string pattern = #"^(\s+)?([-])?(\s+)?(\d+)?([,.])?(\d+)(\s+)?$";
input = input.Replace("\'", ""); // Remove thousand's separator
System.Text.RegularExpressions.Regex.IsMatch(input, pattern);
// if server culture = de then reverse the below replace
input = input.Replace(',', '.');
}
Edit:
Oh oh - just realized that's where we run into a little bit of a problem if an en-us user uses ',' as thousand's separator....
So here a better one:
string input = "+123,456";
if (!string.IsNullOrWhiteSpace(input))
{
string pattern = #"^(\s+)?([+-])?(\s+)?(\d+)?([.,])?(\d+)(\s+)?$";
input = input.Replace(',', '.'); // Ensure no en-us thousand's separator
input = input.Replace("\'", ""); // Remove thousand's separator
input = System.Text.RegularExpressions.Regex.Replace(input, #"\s", ""); // Remove whitespaces
bool foo = System.Text.RegularExpressions.Regex.IsMatch(input, pattern);
if (foo)
{
bool de = false;
if (de) // if server-culture = de
input = input.Replace('.', ',');
double d = 0;
bool bar = double.TryParse(input, out d);
System.Diagnostics.Debug.Assert(foo == bar);
Console.WriteLine(foo);
Console.WriteLine(input);
}
else
throw new ArgumentException("input");
}
else
throw new NullReferenceException("input");
Edit2:
Instead of going through the hassle of getting the server culture, just use the tryparse overload with the culture and don't resubstitute the decimal separator.
double.TryParse(input
, System.Globalization.NumberStyles.Any
, new System.Globalization.CultureInfo("en-US")
, out d
);

XOR reverse a string in objective-c get an error

I want to use the following code to reverse a char * type string in objective-c:
- (char *)reverseString:(char *)aString
{
unsigned long length = strlen(aString);
int end = length - 1;
int start = 0;
while (start < end) {
aString[start] ^= aString[end];
aString[end] ^= aString[start];
aString[start] ^= aString[end];
++start;
--end;
}
return aString;
}
But I got an error EXC_BAD_ACCESS at this line
aString[start] ^= aString[end]
I googled and found people said I can't modify a literal string because it is readonly. I am new to C so I wonder what simple data type (no object) I can use in this example? I get the same error when I use (char []) aString to replace (char *) aString.
I assume you're calling this like
[myObj reverseString:"foobar"];
The string "foobar" here is a constant literal string. Its type should be const char *, but because C is braindead, it's char *. But it's still constant, so any attempt to modify it is going to fail.
Declaring the method as taking char[] actually makes no difference whatsoever. When used as a parameter type, char[] is identical to char*.
You have two choices here. The first is to duplicate the string before passing it to the method. The second is to change the method to not modify its input string at all but instead to return a new string as output. Both can be accomplished using strdup(). Just remember that the string returned from strdup() will need to be free()'d later.

NSExpression 1/2

I want to calculate a string, which I'm doing by this:
NSExpression *expression = [NSExpression expressionWithFormat:calculationString];
float result = [[expression expressionValueWithObject:nil context:nil] floatValue];
NSLog(#"%f", result);
The problem is, when calculationstring is 1/2, the result is 0. I tried to change float with double and NSNumber and the %f to %f and %#, but I always just get 0. What to I have to change?
Also if it matters, I am in Europe, so I have commas instead of points for this value, but it shouldn't matter as I am logging with %f which shows it as points. Just for information
Basically, you just need to tell it that you are performing floating point operation,
1.0/2
1.0/2.0
1/2.0
Will all work
Typing in NSExpression is much like in C: literals that look like integers (no decimal point/comma) are treated as integers and thus use integer division. (Under integer division, 1/2 is zero. If you want 0.5, you need floating point division.) This happens when the expression is parsed and evaluated, so attempting to change the type of the result or the formatting of the output has no effect -- those things happen after parsing and evaluation.
If your calculationString is entirely under your control, it's easy to make sure that you use floating point literals anywhere you want floating point division. (That is, use 1.0/2 instead of 1/2.) If not, you'll need to change it such that it does -- here it's probably better to decompose the parsed NSExpression and change an operand rather than munge the string.
Followup edit on the "decompose" bit: String munging in content that you know to have higher-order structure is generally problematic. And with NSExpression, you already have a parser (who's smarter than a simple regex) decomposing the string for you — that is in fact what NSExpression is all about.
So, if you're working with a user-provided string, don't try to change the expression by changing the string. Let NSExpression parse it, then use properties of the resulting object to pick it apart into its constituent expressions. If your string is simply "1/2", then your expression has an array of two arguments and the function "divide:by:" — you can replace it with an equivalent function where one of the arguments is explicitly a floating-point value:
extension NSExpression {
var floatifiedForDivisionIfNeeded: NSExpression {
if function == "divide:by:", let args = arguments, let last = args.last,
let firstValue = args.first?.constantValue as? NSNumber {
let newFirst = NSExpression(forConstantValue: firstValue.doubleValue)
return NSExpression(forFunction: function, arguments: [newFirst, last])
} else {
return self
}
}
}
I think You need to User DDMathParser Which is best in this situation. I have used it in One of my project which is facing same problem as you have faced
DDMathEvaluator *eval = [DDMathEvaluator defaultMathEvaluator];
id value=[eval evaluateString:#"1/2" withSubstitutions:nil error:&error];
NSLog(#"Result %#",value);
Result 0.5
Rickster's solution worked, but had problems with expressions like 5*5/2, where the first argument (here 5*5) was not just a number.
I found a different solution here that works for me: https://stackoverflow.com/a/46554342/6385925
for people who still have this problem i did a somewhat quick fix:
extension String {
var mathExpression: String {
var returnValue = ""
for value in newString.components(separatedBy: " ") {
if value.isOperator {
returnValue += value
} else {
returnValue += "\(Double(value) ?? 0)"
}
}
return returnValue
}
var isOperator: Bool {
["+", "-", "/", "x", "*"].contains(self)
}
}

c, obj c enum without tag or identifier

im learning cocos2d [open gl wrapper for objective C on iPhone], and now playing with sprites have found this in a example,
enum {
easySprite = 0x0000000a,
mediumSprite = 0x0000000b,
hardSprite = 0x0000000c,
backButton = 0x0000000d,
magneticSprite = 0x0000000e,
magneticSprite2 = 0x0000000f
};
...
-(id) init
{...
/second sprite
TSprite *med = [TSprite spriteWithFile:#"butonB.png"]; //blue
[med SetCanTrack:YES];
[self addChild: med z:1 tag:mediumSprite];
med.position=ccp(299,230);
[TSprite track:med];
so the variable defined in the enum is used in the tag name of the created sprite object,
but i don understand
why give values in hexa to the tags to use
the enum with out tags
as I knew this enum in obj C and C
typedef enum {
JPG,
PNG,
GIF,
PVR
} kImageType;
thanks!
Usually, when you are creating an enum, you want to use it as a type (variable, method parameters etc.).
In this case, it's just a way how to declare integer constants. Since thay don't want to use the enum as type, the name is not necessary.
Edit:
Hexadecimal numbers are commonly used when the integer is a binary mask. You won't see any operators like +,-,*,/ used with such a number, you'll see bitwise operators (!, &, |, ^).
Every digit in a hexadecimal number represents 4 bits. The whole number is a 32-bit integer and by writing it in hexadecimal in this case, you are saying that you are using only the last four bits and the other bits can be used for something else. This wouldn't be obvious from a decimal number.
Enums are automatically assigned values, incremented from 0 but you can assign your own values.
If you don't specify any values they will be starting from 0 as in:
typedef enum {
JPG,
PNG,
GIF,
PVR
} kImageType;
But you could assign them values:
typedef enum {
JPG = 0,
PNG = 1,
GIF = 2,
PVR = 3
} kImageType;
or even
typedef enum {
JPG = 100,
PNG = 0x01,
GIF = 100,
PVR = 0xff
} kImageType;
anything you want, repeating values are ok as well.
I'm not sure why they are given those specific values but they might have some meaning related to use.
Well, you seem to be working off a terrible example. :)
At least as far as enums are concerned. It's up to anyone to define the actual value of an enum entry, but there's no gain to use hex numbers and in particular there's no point in starting the hex numbers with a through f (10 to 15). The example will also work with this enum:
enum {
easySprite = 10,
mediumSprite,
hardSprite,
backButton,
magneticSprite,
magneticSprite2
};
And unless there's some point in having the enumeration start with value 10, it will probably work without specifying any concrete values.