iPhone - Creating variadic functions in objective c issue - iphone

I referred this SO Answer for creating variadic function in objective C.
I tested your code by passing arguments like below:
[self logMessage:#"string: %#\n number: %#\n image: %#",
#"asdf",
[NSNumber numberWithInt:23],
[UIImage imageNamed:#"local.png"]];
and edited the code with NSLog();
- (void)logMessage:(NSString *)format, ... {
va_list args;
va_start(args, format);
id arg = nil;
int i = 1;
NSLogv(format, args);
while ((arg = va_arg(args,NSString *))) {
NSLog(#"val: %d", i++);
/// Do your thing with arg here
//NSString *name = NSStringFromClass([arg class]);
//NSLog(#"string: %#", name);
}
va_end(args);
}
But the output as follows:
2012-09-28 19:34:45.271 SIMO[2384:c07] string: asdf
number: 23
image: <UIImage: 0x8151f80>
2012-09-28 19:34:45.273 SIMO[2384:c07] val: 1
2012-09-28 19:34:45.273 SIMO[2384:c07] val: 2
2012-09-28 19:34:45.274 SIMO[2384:c07] val: 3
2012-09-28 19:34:45.274 SIMO[2384:c07] val: 4
2012-09-28 19:34:45.274 SIMO[2384:c07] val: 5
2012-09-28 19:34:45.275 SIMO[2384:c07] val: 6
2012-09-28 19:34:45.275 SIMO[2384:c07] val: 7
2012-09-28 19:34:45.276 SIMO[2384:c07] val: 8
This tells that the argument is 8, but I passed only 3 (NSString, NSNumber, UIImage)
I can't get the concept.. Could you clarify me
Could anyone clarify this

va_arg doesn't really know when the argument list ends. The approach you're using expects the argument list to be terminated by nil, like +[NSArray arrayWithObjects:].
So either change your invocation to add nil at the end of the argument list, or find some other way of knowing when the arguments are over (e.g. for a printf clone, you might know the number of format arguments from the format string itself).

Related

Unable to convert UInt64 to hexadecimal?

I'm using a C function in my Swift code which produces the following result (when called in Swift):
let result: UInt64 = 586512487604551679
When I call the function in C, I get:
8229a7fffffffff
However, when I convert the Swift result to hexadecimal, I get a different value.
let hex = String(result, radix: 16, uppercase: false)
print(hex) // 823b5ffffffffff
When I print from C, I use the following print statement:
printf("The index is: %" PRIx64 "\n", indexed);
What is the PRIx64 format and is that what's causing the discrepancy? In C, the value is of type uint64_t.
I've no idea what PRIx64 is. I did this:
uint64_t t = 586512487604551679;
NSString* s = [NSString stringWithFormat:#"%llx", t];
NSLog(#"%#", s); // 823b5ffffffffff
and
let t : UInt64 = 586512487604551679
let s = String(t, radix:16)
print(s) // 823b5ffffffffff

error during token replacement in macros

I wrote this small program expecting that the values will be placed and it would see the output but i get an error:
D:\C Programming\token-pasting.c||In function 'main':|
D:\C Programming\token-pasting.c|6|error: 'Hell23' undeclared (first use in this function)|
D:\C Programming\token-pasting.c|6|note: each undeclared identifier is reported only once for each function it appears in|
||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|
#include <stdio.h>
#define swap(front, back) front##back
main()
{
swap(Hell, 23) ;
return 0;
}
There's a million ways to print "hell21", still need context. And ditch your "swap" macro...
char *str = "hell";
int x = 21;
printf("%s%d", str, x);
%s says to replace that part of printf with a string array, %d says to replace that part of printf with an integer.

Character at index issue

I have the following
NSString *timeString = [NSString stringWithFormat:#"%i", time];
NSLog(#"Timestring is %#", timeString);
NSLog(#"the character at 1 is %d", [timeString characterAtIndex:1]);
and get the following in the print outs
Timestring is 59
the character at 1 is 57
If I print out characterAtIndex:0 it prints out
Timestring is 59
the character at 0 is 53
I think it is printing out the char representation of the number.
How could I do this so that I can extract both numbers from e.g. 60 and use the 6 and the 0 to set an image.
e.g. #"%d.png"
format specifier %d make nslog to treat corresponding value as integer, so in your case char value is treated as integer and integer value printed. To output actual character use %c specifier:
NSLog(#"the character at 1 is %c", [timeString characterAtIndex:1]);

#'Event$variable' iphone Object C

$variable =1;
How i can do it?
I need insert variable 1 2 3 4 5 ...
in #"Event" or #'Event'
Stabbing in the dark here, but is this what you want?
int variable = 1;
NSString *str = [NSString stringWithFormat:#"Event%d", variable];

how to split a string on the iPhone?

I have got below value(dynamic) from the server:
drwxr-xr-x 9 0 0 4096 Jan 10 05:30 California
Now i want to get valu like this.
drwxr-xr-x
9
0
0
4096
Jan 10
05:30
California
Please help me for this question
you can try smth like this
NSArray* components = [initialString componentsSeparatedByString:#" "];
See NSString componentsSeparatedByString for your answer.
As others have mentioned, you can use NSString's member function componentsSeparatedByString: or componentsSeparatedByCharactersInSet:
As an alternative (for more powerful tokenizing), look into the Objective-C NSScanner class in the foundation framework of Mac OS X.
You could do something like this:
NSString *str = "drwxr-xr-x 9 0 ... ";
NSScanner *scanner = [NSScanner scannerWithString:str];
In order to obtain each token in string form, use NSScanner's scanUpToCharactersFromSet:intoString: member function.
NSString *token = [NSString string];
NSCharacterSet *div = [NSCharacterSet whitespaceCharacterSet];
[scanner scanUpToCharactersFromSet:div intoString:token];
// token now contains #"drwxr-xr-x"
Subsequent calls to the above would return 9, 0, and so on.
Note: the code above has not been tested.
[myStringValue componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
may be useful as well.
Use a regex: RegexKitLite.
This is a "complete example" of a way to use a regex to do what you want with a lot of explanation, so it's a bit of a long answer. The regex used is just one way to do this, and is "fairly permissive" in what it accepts. The example shows:
How to match more than "one line / directory" at once.
A possible way to handle different date formats (Jan 10 05:30 and Apr 30 2009)
How to create an "array of arrays" of matches.
Iterate over the matched array and create a NSDictionary based on the parsed results.
Create a "comma separated values" version of the results.
Note: The example splits up some of its long strings across multiple lines. A string literal in the form of #"string1 " #"string2" will be "automagically" concatenated by the compiler to form a string that is equivalent to #"string 1 string2". I note this only because this might look a bit unusual if you're not used to it.
#import <Foundation/Foundation.h>
#import "RegexKitLite.h"
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *stringToMatch =
#"drwxr-xr-x 9 0 0 4096 Jan 10 05:30 California\n"
#"-rw-r--r-- 1 johne staff 1335 Apr 30 2009 tags.m"; // A random entry from my machine with an "older" date.
NSString *regex =
#"(?m)^" // (?m) means: to "have ^ and $ match new line boundaries". ^ means: "Match the start of a line".
// Below,
// (...) means: "Capture for extraction the matched characters". Captures start at 1, capture 0 matches "everything the regex matched".
// [^\\p{Z}]+ says: "Match one or more characters that are NOT 'Separator' characters (as defined by Unicode, essentially white-space)".
// In essence, '[^\\p{Z}]+' matches "One or more non-white space characters."
// \\s+ says: Match one or more white space characters.
// ([^\\p{Z}]+)\\s+ means: Match, and capture, the non-white space characters, then "gobble up" the white-space characters after the match.
#"([^\\p{Z}]+)\\s+" // Capture 1 - Permission
#"([^\\p{Z}]+)\\s+" // Capture 2 - Links (per `man ls`)
#"([^\\p{Z}]+)\\s+" // Capture 3 - User
#"([^\\p{Z}]+)\\s+" // Capture 4 - Group
#"([^\\p{Z}]+)\\s+" // Capture 5 - Size
#"(\\w{1,3}\\s+\\d+\\s+(?:\\d+:\\d+|\\d+))\\s+" // Capture 6 - The "date" part.
// \\w{1,3} means: One to three "word-like" characters (ie, Jan, Sep, etc).
// \\d+ means: Match one or more "digit-like" characters.
// (?:...) means: Group the following, but don't capture the results.
// (?:.A.|.B.) (the '|') means: Match either A, or match B.
// (?:\\d+:\\d+|\\d+) means: Match either '05:30' or '2009'.
#"(.*)$"; // Capture 7 - Name. .* means: "Match zero or more of any character (except newlines). $ means: Match the end of the line.
// Use RegexKitLites -arrayOfCaptureComponentsMatchedByRegex to create an
// "array of arrays" composed of:
// an array of every match of the regex in stringToMatch, and for each match,
// an array of all the captures specified in the regex.
NSArray *allMatchesArray = [stringToMatch arrayOfCaptureComponentsMatchedByRegex:regex];
NSLog(#"allMatchesArray: %#", allMatchesArray);
// Here, we iterate over the "array of array" and create a NSDictionary
// from the results.
for(NSArray *lineArray in allMatchesArray) {
NSDictionary *parsedDictionary =
[NSDictionary dictionaryWithObjectsAndKeys:
[lineArray objectAtIndex:1], #"permission",
[lineArray objectAtIndex:2], #"links",
[lineArray objectAtIndex:3], #"user",
[lineArray objectAtIndex:4], #"group",
[lineArray objectAtIndex:5], #"size",
[lineArray objectAtIndex:6], #"date",
[lineArray objectAtIndex:7], #"name",
NULL];
NSLog(#"parsedDictionary: %#", parsedDictionary);
}
// Here, we use RegexKitLites -stringByReplacingOccurrencesOfRegex method to
// create a new string. We use it to essentially transform the original string
// in to a "comma separated values" version of the string.
// In the withString: argument, '$NUMBER' means: "The characters that were matched
// by capture group NUMBER."
NSString *commaSeparatedString = [stringToMatch stringByReplacingOccurrencesOfRegex:regex withString:#"$1,$2,$3,$4,$5,$6,$7"];
NSLog(#"commaSeparatedString:\n%#", commaSeparatedString);
[pool release];
pool = NULL;
return(0);
}
Compile and run with:
shell% gcc -Wall -Wmost -arch i386 -g -o regexExample regexExample.m RegexKitLite.m -framework Foundation -licucore
shell% ./regexExample
2010-01-14 00:10:38.868 regexExample[49409:903] allMatchesArray: (
(
"drwxr-xr-x 9 0 0 4096 Jan 10 05:30 California",
"drwxr-xr-x",
9,
0,
0,
4096,
"Jan 10 05:30",
California
),
(
"-rw-r--r-- 1 johne staff 1335 Apr 30 2009 tags.m",
"-rw-r--r--",
1,
johne,
staff,
1335,
"Apr 30 2009",
"tags.m"
)
)
2010-01-14 00:10:38.872 regexExample[49409:903] parsedDictionary: {
date = "Jan 10 05:30";
group = 0;
links = 9;
name = California;
permission = "drwxr-xr-x";
size = 4096;
user = 0;
}
2010-01-14 00:10:38.873 regexExample[49409:903] parsedDictionary: {
date = "Apr 30 2009";
group = staff;
links = 1;
name = "tags.m";
permission = "-rw-r--r--";
size = 1335;
user = johne;
}
2010-01-14 00:10:38.873 regexExample[49409:903] commaSeparatedString:
drwxr-xr-x,9,0,0,4096,Jan 10 05:30,California
-rw-r--r--,1,johne,staff,1335,Apr 30 2009,tags.m