This question already has an answer here:
which is the correct specifier to use for long when calling stringWithFormat?
(1 answer)
Closed 2 years ago.
I try to convert long (value: 454555) to NSString. But everytime I had tried it, I got garbage value like #"-5026338884877204098".
How can I convert it same with 454555?
You can initialize a NSString by
NSString *a = #(454555).stringValue;
Here you can put all mathematical type value in the brackets,like
NSString *a = #(0.1).stringValue;//a float value
NSString *a = #(9223372036854775807).stringValue;//it's a longlong value
Try
long l = 454555;
NSString * s = [NSString stringWithFormat:#"%ld", l];
Note this is not locale aware ... but handy and sounds like the man you are looking for for your job. Here the %ld means a l=long d=decimal/int (ie long) value is next up in the parameters.
EDIT
If you like the #-way just execute the code below.
int main(int argc, const char * argv[]) {
#autoreleasepool
{
NSLog(#"Hello, World!");
for ( long i = 0; i < 1000000; i ++ )
{
// Direct ...
NSString * s = [NSString stringWithFormat:#"%ld", i ];
}
NSLog(#"1");
for ( long i = 0; i < 1000000; i ++ )
{
// Indirect via NSNumber ...
NSString * s = #(i).stringValue;
}
NSLog(#"2");
}
return 0;
}
Related
This question already has answers here:
NSString (hex) to bytes
(7 answers)
Closed 3 years ago.
I have a string and I'm trying to break it up and add it to an NSArray. I've recently moved from Java (android) to iOS... I wrote a java function which converted a hexString/string to a byte array. I can't see an obvious way to do it with objective-c. Not sure what I've attempted is even close to achieving what I need.
Heres my string
NSString *code = #"11111bfb";
This is the output I hope to achieve
NSArray *codeArray = #[#0x11, #0x11, #0x1b, #0xfb];
Method
- (NSData *)dataFromHexString:(NSString *) string {
if([string length] % 2 == 1){
string = [#"0x"stringByAppendingString:string];
}
const char *chars = [string UTF8String];
int i = 0, len = (int)[string length];
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[4] = {'\0','\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:1];
}
return data;
}
So it seems this returns the format I need.
NSString * inputStr = #"11111bfb";
NSMutableArray *charByteArray = [[NSMutableArray alloc]initWithCapacity:1];
int i = 0;
for (i = 0; i+2 <= inputStr.length; i+=2) {
NSRange range = NSMakeRange(i, 2);
NSString* charStr = [inputStr substringWithRange:range];
[charByteArray addObject:[NSString stringWithFormat:#"0x%#",charStr]];
}
I have two NSData objects, data1 and data2, and I'd like to do a bit-wise XOR and store the result in a third NSData object, xorData.
The first thing I tried was this:
*data1.bytes^*data2.bytes;
but it gave an error of:
Invalid operands to binary expression ('const void' and 'const void')
So I tried to write a function that would extract the bytes of the data into an array of integers, perform the xor on the integers, then save the result back into an NSData object. The function looks like this:
+(NSData *) DataXOR1:(NSData *) data1
DataXOR2:(NSData *)data2{
const int *data1Bytes = [data1 bytes];
const int *data2Bytes = [data2 bytes];
NSMutableArray *xorBytes = [[NSMutableArray alloc] init ];
for (int i = 0; i < data1.length;i++){
[xorBytes addObject:[NSNumber numberWithInt:(data1Bytes[i]^data2Bytes[i])]];
}
NSData *xorData = [NSKeyedArchiver archivedDataWithRootObject:xorBytes];
return xorData;
}
This runs, but gives the wrong answers. When I test it on two simple pieces of data (data1 = 0x7038 and data2 = 0x0038), and use NSLog to output what the values are, I get:
data1Bytes[0] = 8070450532247943280
data2Bytes[0] = 8070450532247943168
data1Bytes[0]^data2Bytes[0] = 112
data1Bytes[1] = 10376302331560798334
data2Bytes[1] = 10376302331560798334
data1Bytes[1]^data2Bytes[1] = 0
This boggles my mind a bit because the values in the dataXBytes arrays are totally wrong, but they're xor-ing to the right values! (0x70 ^ 0x00 = 0x70 = 112)
I think it might be an endian-ness problem, but when I change the initialization of data1Bytes to:
const int *data1Bytes = CFSwapInt32BigToHost([data1 bytes]);
it runs into an error when it tries to access it, saying:
Thread 1: EXC_BAD_ACCESS(code=1, address = 0xa08ad539)
Is there a much simpler way to do the xor? If not, how can I fix the endian problem?
Casting to int then archiving an NSArray of NSNumbers will definitely not create the result you're looking for. You'll want to have some mutable NSData to which you append the individual bytes to, something like
+(NSData *) DataXOR1:(NSData *) data1
DataXOR2:(NSData *)data2{
const char *data1Bytes = [data1 bytes];
const char *data2Bytes = [data2 bytes];
// Mutable data that individual xor'd bytes will be added to
NSMutableData *xorData = [[NSMutableData alloc] init];
for (int i = 0; i < data1.length; i++){
const char xorByte = data1Bytes[i] ^ data2Bytes[i];
[xorData appendBytes:&xorByte length:1];
}
return xorData;
}
+ (NSData *) xorData:(NSData *)data1 with:(NSData *)data2
{
// make data1 smaller
if (data1.length > data2.length) {
NSData *t = data1;
data1 = data2;
data2 = t;
}
char *xor = (char *) malloc(data2.length * sizeof(char));
char * data1Bytes = (char *) data1.bytes;
char * data2Bytes = (char *) data2.bytes;
for (int i = 0; i <data1.length; i++)
{
xor[i] = data1Bytes[i] ^ data2Bytes[i];
}
NSMutableData *data = [[[NSMutableData alloc] initWithBytes:xor length:data1.length] autorelease];
[data appendData:[data2 subdataWithRange:NSMakeRange(data1.length, data2.length - data1.length)]];
free(xor);
return [NSData dataWithData:data];
}
I am writing reverseString function by myself. (For test use) And I use iOS platform to run my c code, which sounds weird, but again, for test use...
Here is my code:
-(char *) reverseString:(char *)str
{
char *end = str;
char tmp;
if (str)
{
while (*end) { end++; }
--end;
NSLog(#"%c", *end);
while (end>str)
{
tmp = *str;
*str = *end;
str++;
*end = tmp;
end--;
}
}
NSLog(#"%s", str);
return str;
}
After running the function by calling:
char *testChar = "abcd";
[self reverseString:testChar];
I received the error on line:
*str = *end;
Thread 1: EXC_BAD_ACCESS(code=2, address=0x2de4)
I don't really know understand what's wrong with the pointer here...Anyone has any idea?
You can't modify a string literal. Use a char array instead.
char testChar[] = "abcd";
For example, I need the NSString have at least 8 chars....instead of using a loop to add the left pad spaces on this, is there anyway to do it?
Examples:
Input: |Output:
Hello | Hello
Bye | Bye
Very Long |Very Long
abc | abc
Here is an example of how you can do it:
int main (int argc, const char * argv[]) {
NSString *str = #"Hello";
int add = 8-[str length];
if (add > 0) {
NSString *pad = [[NSString string] stringByPaddingToLength:add withString:#" " startingAtIndex:0];
str = [pad stringByAppendingString:str];
}
NSLog(#"'%#'", str);
return 0;
}
I just do something like this:
NSLog(#"%*c%#", 14 - theString.length, ' ', theString);
Moreover, 14is the width that you want.
You can use C language printf formatting with -[NSMutableString appendFormat:] and all other NSString "format" methods. It doesn't respect NSString (do formatting on %#), so you need to convert them to ASCII.
String Padding in C
- (NSString *)sample {
NSArray<NSString *> *input = #[#"Hello", #"Bye", #"Very Long", #"abc"];
NSMutableString *output = [[NSMutableString alloc] init];
for (NSString *string in input) {
[output appendFormat:#"%8s\n", string.UTF8String];
}
return output;
}
/*
Return value:
Hello
Bye
Very Long
abc
*/
if you need the same answer in a method, I had to create one for use in my projects. original code by dashblinkenlight
- (NSString *) LeftPadString: (NSString*) originalString LengthAfterPadding: (int)len paddingCharacter: (char) pad
{
int add = (int) (len - originalString.length);
NSString* paddingCharString = [NSString stringWithFormat:#"%c" , pad];
if (add > 0)
{
NSString *pad = [[NSString string] stringByPaddingToLength:add withString: paddingCharString startingAtIndex:0];
return [pad stringByAppendingString:originalString];
}
else
return originalString;
}
I've been doing a lot of reading on how to convert a string to a hex value. Here is what I found to accomplish this:
NSString * hexString = [NSString stringWithFormat:#"%x", midiValue];
This returned some "interesting" results and upon reading a little further I found a post that mentioned this
"You're passing a pointer to an object representing a numeric value, not the numeric value proper."
So I substituted 192 instead of "midiValue" and it did what I expected.
How would I pass the string value and not the pointer?
Decleration of midiValue:
NSString *dMidiInfo = [object valueForKey:#"midiInformation"];
int midiValue = dMidiInfo;
You probably need to do something like this:
NSNumberFormatter *numberFormatter= [[NSNumberFormatter alloc] init];
int anInt= [[numberFormatter numberFromString:string ] intValue];
also, I think there is some example code in the xcode documentation for converting to and from a hex value, in the QTMetadataEditor sample. in the MyValueFormatter class.
+ (NSString *)hexStringFromData:(NSData*) dataValue{
UInt32 byteLength = [dataValue length], byteCounter = 0;
UInt32 stringLength = (byteLength*2) + 1, stringCounter = 0;
unsigned char dstBuffer[stringLength];
unsigned char srcBuffer[byteLength];
unsigned char *srcPtr = srcBuffer;
[dataValue getBytes:srcBuffer];
const unsigned char t[16] = "0123456789ABCDEF";
for (; byteCounter < byteLength; byteCounter++){
unsigned src = *srcPtr;
dstBuffer[stringCounter++] = t[src>>4];
dstBuffer[stringCounter++] = t[src & 15];
srcPtr++;
}
dstBuffer[stringCounter] = '\0';
return [NSString stringWithUTF8String:(char*)dstBuffer];
}
+ (NSData *)dataFromHexString:(NSString*) dataValue{
UInt32 stringLength = [dataValue length];
UInt32 byteLength = stringLength/2;
UInt32 byteCounter = 0;
unsigned char srcBuffer[stringLength];
[dataValue getCString:(char *)srcBuffer];
unsigned char *srcPtr = srcBuffer;
Byte dstBuffer[byteLength];
Byte *dst = dstBuffer;
for(; byteCounter < byteLength;){
unsigned char c = *srcPtr++;
unsigned char d = *srcPtr++;
unsigned hi = 0, lo = 0;
hi = charTo4Bits(c);
lo = charTo4Bits(d);
if (hi== 255 || lo == 255){
//errorCase
return nil;
}
dstBuffer[byteCounter++] = ((hi << 4) | lo);
}
return [NSData dataWithBytes:dst length:byteLength];
}
Hopefully this helps.
if you are messing with a simple iPhone app in Xcode using the iPhone 5.1 Simulator then this is useful:
//========================================================
// This action is executed whenever the hex button is
// tapped by the user.
//========================================================
- (IBAction)hexPressed:(UIButton *)sender
{
// Change the current base to hex.
self.currentBase = #"hex";
// Aquire string object from text feild and store in a NSString object
NSString *temp = self.labelDisplay.text;
// Cast NSString object into an Int and the using NSString method StringWithFormat
// which is similar to c's printf format then output into hexidecimal then return
// this NSString object with the hexidecimal value back to the text field for display
self.labelDisplay.text=[NSString stringWithFormat:#"%x",[temp intValue]];
}