Recognizing few integers in NSString - iphone

I am receiving a string from server in this format:
0_1_2_3
My task is to select for digits from this string to fill four labels with them.
First idea was:
NSString *res1 = [result substringWithRange:NSMakeRange(0, 1)];
[firstLabel setText:res1];
four times with appropriate labels.
But operation will repeats many times and every time I will receive a string with increased digit values. So when every digit be a decimal this code will not work. So how can I track every digit independently from their length in a proper way?

NSString comes with a convenience method called -componentsSeparatedByString:
NSString *myString = #"0_1_2_3";
NSArray *myDigitStrings = [myString componentsSeparatedByString:#"_"];
/* access digit strings from myDigitStrings array by index or fast enumeration... */
for (NSString *myDigitString in myDigitStrings)
NSLog(#"digit string: %#", myDigitString);

Related

Convert NSNumber to hex string with 16 digits

I have to convert an NSNumber to a hex string like follows:
return [NSString stringWithFormat:#"%llX", self.unsignedLongLongValue];
Unfortunately, this will sometimes give me string like 93728A166D1A287 where they should be 093728A166D1A287, depending on the number.
Hint: the leading 0.
I've also tried it with:
return [NSString stringWithFormat:#"%16.llX", self.unsignedLongLongValue];
without success.
I could do something like this, but that just sucks:
- (NSString *)hexValue {
NSString *hex = [NSString stringWithFormat:#"%llX", self.unsignedLongLongValue];
NSUInteger digitsLeft = 16 - hex.length;
if (digitsLeft > 0) {
NSMutableString *zeros = [[NSMutableString alloc] init];
for (int i = 0; i < digitsLeft; i++) [zeros appendString:#"0"];
hex = [zeros stringByAppendingString:hex];
}
return hex;
}
So finally my question, is there a way to enforce the string to be 16 characters?
If you need to zero-pad your hex numbers, use zero in front of the format specifier, like this:
return [NSString stringWithFormat:#"%016llX", self.unsignedLongLongValue];
This should take care of formatting your number with 16 digits, regardless of how many "meaningful" digits the number has.
Here is a demo of this format string in plain C (this part is shared between the two languages).
Use:
return [NSString stringWithFormat:#"%016llX", self.unsignedLongLongValue];
Which sets leading 0 and the length of the output string.

iPhone iOS how to count number of case-insensitive occurrences of a word within a string?

I'm looking for a way to search an arbitrary long string (10000 characters) and find the number of times a specific keyword is repeated in the string. How can this be done?
I have this method, that pretty much counts the number of fragments left after the string is split around keywords, but it is not case insensitive.
-(void)countKeywords
{
NSArray* components = [self.salesCopy componentsSeparatedByString:#"search term"];
NSLog(#"search term number found: %i",components.count);
}
What's a better way to count the number of keywords within a string?
Splitting the string, counting parts, and throwing them away is not efficient. Searching for substring repeatedly without creating new objects would definitely be more efficient. Since the string is relatively long, you may benefit from implementing an advanced string search algorithm, for example Knuth-Morris-Pratt, to significantly decrease your search time.
Here is an implementation that should be faster than your splitting code:
NSString *str = #"Hello sun, hello bird, hello my lady! Hello breakfast, May I buy you again tomorrow?";
NSRange r = NSMakeRange(0, str.length);
int count = 0;
for (;;) {
r = [str rangeOfString:#"hello" options:NSCaseInsensitiveSearch range:r];
if (r.location == NSNotFound) {
break;
}
count++;
r.location++;
r.length = str.length - r.location;
}
NSLog(#"%d", count);
Just create copies of both self.salesCopy and the searchTerm, set the copies to lower case via [NSString lowercaseString], then perform your code, and you'll have the count
-(void)countKeywords
{
NSString *lowerCaseSalesCopy = [self.salesCopy lowercaseString];
NSString *lowerCaseSearchTerm = [searchTerm lowercaseString];
NSArray* components = [lowerCaseSalesCopy componentsSeparatedByString:lowerCaseSearchTerm];
NSLog(#"search term number found: %i",components.count);
}
I am not 100% sure that could help you, but may do some of the job you need (if not all):
NSRange ran = [yourString rangeOfString:wordToLookFor options:NSCaseInsensitiveSearch];
And look at
ran.length
ran.location
ran.location will provide you the location within the string of the first occurrence. You could then cut the string after this occurrence, and run this again until the end of the string.

iPhone - Truncate String to Last Four

All,
I can't seem to find the answer I'm looking for using search so I'll ask it.
I need to pull the last four digits of a credit card number out and set it into another string. It needs to account for the variances in credit card number lengths (i.e. 16 numbers or 15 numbers, etc)
i.e. if the number was "1234567890123456" I would want to set a new string as "3456".
Thanks
Assuming the credit card number is stored as a string:
NSString *lastFour = [fullNumber substringFromIndex:[fullNumber length] - 4];
Assuming it's an unsigned integer of any wide-enough type:
NSString *lastFour = [NSString stringWithFormat: #"%04u", (unsigned int)(fullNumber % 10000)];
NSString *newString = [oldString substringFromIndex:[oldString length] - 4];

Trying to save long long into NSNumber from String

I am trying to save a long long number (received as a string) such as '80182916772147201' into an NSNumber.
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterBehaviorDefault];
[item setObject:[f numberFromString:#"80182916772147201"] forKey:#"theID"];
[f release];
When I NSLog this out, assuming the string was '80182916772147201' I get:
NSLog(#"%lld", [[item objectForKey:#"theID"] longLongValue]);
Returns: '80182916772147200' - Note the rounded down final digit.
What am I doing wrong?
The problem is that NSNumberFormatter has decided to represent that number as a floating-point number. To force it to use integers only:
[f setAllowsFloats:NO];
Can you try this?
NSString *numStr = [NSString stringWithFormat:#"%llu", [myNum unsignedLongLongValue]];
This makes a few reasonable assumptions such as numStr will only contain numeric digits and it contains a 'valid' unsigned long long value. A drawback to this approach is that UTF8String creates what essentially amounts to [[numStr dataUsingEncoding:NSUTF8StringEncoding] bytes], or in other words something along the lines of 32 bytes of autoreleased memory per call. For the vast majority of uses, this is no problem what-so-ever.
For an example of how to add something like unsignedLongLongValue to NSString that is both very fast and uses no autoreleased memory as a side effect, take a look at the end of my (long) answer to this SO question. Specifically the example implementation of rklIntValue, which would require only trivial modifications to implement unsignedLongLongValue.

objective-c code to right pad a NSString?

Can someone give a code example of how to right pad an NSString in objective-c please?
For example want these strings:
Testing 123 Long String
Hello World
Short
if right padded to a column width of say 12: and then a sting "XXX" is added to the end of each, it would give:
Testing 123 xxx
Hello World xxx
Short xxx
That is a 2nd column would like up.
Adam is on the right track, but not quite there. You do want to use +stringWithFormat:, but not quite as he suggested. If you want to pad "someString" to (say) a minimum of 12 characters, you'd use a width specifier as part of the format. Since you want the result to be left-justified, you need to precede the width specifier with a minus:
NSString *padded = [NSString stringWithFormat:#"%-12#", someString];
Or, if you wanted the result to be exactly 12 characters, you can use both minimum and maximum width specifiers:
NSString *padded = [NSString stringWithFormat:#"%-12.12#", someString];
2nd column of what would line up?
Given that you are on iOS, using HTML or a table view would be far more straightforward than trying to line up characters with spaces. Beyond being programmatically more elegant, it will look better, be more resilient to input data changes over time, and render a user experience more in line with expectations for the platform.
If you really want to use spaces, then you are going to have to limit your UI to a monospace font (ugly for readability purposes outside of specific contexts, like source code) and international characters are going to be a bit of a pain.
From there, it would be a matter of getting the string length (keeping in mind that "length" does not necessarily mean "# of characters" in some languages), doing a bit of math, using substringWithRange: and appending spaces to the result.
Unfortunately, Objective-C does not allow format specifiers for %#. A work-around for padding is the following:
NSString *padded = [NSString stringWithFormat:#"%#%*s", someString, 12-someString.length, ""];
which will pad the string to the right with spaces up to a field length of 12 characters.
%-# does not work, but %-s works
NSString *x = [NSString stringWithFormat:#"%-3#", #"a" ];
NSString *y = [NSString stringWithFormat:#"%-3#", #"abcd" ];
NSString *z = [NSString stringWithFormat:#"%-3# %#", #"a", #"bc" ];
NSString *zz = [NSString stringWithFormat:#"%-3s %#", "a", #"bc" ];
NSLog(#"[%#][%#][%#][%#].......", x,y,z,zz);
output:
[a][abcd][a bc][a bc].......
Try below. its working for me.
NSString *someString = #"1234";
NSString *padded = [someString stringByPaddingToLength: 16 withString: #"x" startingAtIndex:0];
NSLog(#"%#", someString);
NSLog(#"%#", padded);
First up, you're doing this a bad way. Please use separate labels for your two columns and then you will also be able to use proportional fonts. The way you're going about it you should be looking for an iPhone curses library.
If you really have to do it this way just use stringWithFormat:, like:
NSString *secondColumnString = #"xxx";
NSString *spacedOutString = [NSString stringWithFormat:#"testingColOne %#", secondColumnString];
NSString *spacedOutString = [NSString stringWithFormat:#"testingAgain %#", secondColumnString];