How to convert ASCII value to a character in Objective-C? - iphone

I was wondering if anyone has the following php function equivalents in Objective-C for iPhone development:
ord() # returns the ASCII value of the first character of a string.
chr() # returns a character from the specified ASCII value.
Many thanks!

This is how you can work with ASCII values and NSString. Note that since NSString is working with unichars, there could be unexpected results for a non ASCII string.
// NSString to ASCII
NSString *string = #"A";
int asciiCode = [string characterAtIndex:0]; // 65
// ASCII to NSString
int asciiCode = 65;
NSString *string = [NSString stringWithFormat:#"%c", asciiCode]; // A

//char to int ASCII-code
char c = 'a';
int ascii_code = (int)c;
//int to char
int i = 65; // A
c = (char)i;

Related

NSString unichar from int

I have an int value which I obtained from the character 爸, which is 29240. I can convert this number to hex, but I have no clue how to write the chinese character out in an NSString with only the int 29240.
Basically, what I did was:
NSString * s = #"爸";
int a = [s characterAtIndex:0];
NSLog(#"%d", a);
What it gave as output was 29240.
However, I don't know how to create an NSString that just contains 爸 from only the int 29240.
I converted 29240 into binary which gave me 7238, but I can't seem to create a method which allows me to input any integer and NSLog the corresponding character.
I can hard code it in, so that I have
char cString[] = "\u7238";
NSData *data = [NSData dataWithBytes:cString length:strlen(cString)];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"result string: %#", string);
But I'm not sure how to do it with any int.
Thanks to anyone who can help me!
To create a string from one (or more) Unicode characters use initWithCharacters:
unichar c = 29240;
NSString *string = [[NSString alloc] initWithCharacters:&c length:1];
NSString uses UTF-16 characters internally, so
this works for all characters in the "Basic Multilingual Plane", i.e. all characters up to U+FFFF. The following code works for arbitrary characters:
uint32_t ch = 0x1F60E;
ch = OSSwapHostToLittleInt32(ch); // To make it byte-order safe
NSString *s1 = [[NSString alloc] initWithBytes:&ch length:4 encoding:NSUTF32LittleEndianStringEncoding];
NSLog(#"%#", s1);
// Output: 😎
Try out this code snippet to get you started in the right direction:
NSString *s = #"0123456789";
for (int i = 0; i < [s length]; i++) {
NSLog(#"Value: %d", [s characterAtIndex:i]);
}
Just pass in the character as an integer:
unichar decimal = 12298;
NSString *charStr = [NSString stringWithFormat:#"%C", decimal];

How to convert the Char * to hexadecimal value

I have a char array that i need to convert to hexadecimal value
char* arrrr =[self mountLVparams:NULL :c :code_ward_arr];
int size =strlen(arrrr);
I am trying with this but this not happening
NSData* data = [NSData dataWithBytes:arrrr length:sizeof(sizeof(unsigned char)*size)];
Try this:
NSString *inp = [NSString stringWithString:#"MmMmMm"];
char star = [inp characterAtIndex:3];
NSString *string = [NSString stringWithFormat:#"char:%c andHex:%x",[inp characterAtIndex:3],star];
NSLog(#"%#",string);
Look at in output is "%#" as a regular string. In string you will receive hex value of char.
char:m andHex:6d
With array you will have to do it in a loop
You don't "convert" a value to hexadecimal. Hexadecimal is just a different way of counting or displaying the same numbers.
if (0xFF==255)
{
NSLog(#"255 equals 0xFF");
}
Now see the following code below which will convert your byte array into and int, then display then format the int as a hex string.
-(void) convertData: (unsigned char*) data
{
int numBytes = sizeof(int);
//convert array of bytes to NSData*
NSData* binaryData = [[NSData alloc] initWithBytes: (void*) data length: numBytes];
//read value of number stored in data, presuming it is an integer
int number = *((int*) data);
//format number as a hex string
NSString* hexString = [NSString stringWithFormat:#"%X",number];
}

Detecting if a character is either a letter or a number

In objective-c, how would I check if a single character was either a letter or a number? I would like to eliminate all other characters.
To eliminate non letters:
NSString *letters = #"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
NSCharacterSet *notLetters = [[NSCharacterSet characterSetWithCharactersInString:letters] invertedSet];
NSString *newString = [[string componentsSeparatedByCharactersInSet:notLetters] componentsJoinedByString:#""];
To check one character at a time:
for (int i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if ([notLetters characterIsMember:c]) {
...
}
}
NSCharacterSet *validChars = [NSCharacterSet alphanumericCharacterSet];
NSCharacterSet *invalidChars = [validChars invertedSet];
NSString *targetString = [[NSString alloc] initWithString: #"..."];
NSArray *components = [targetString componentsSeparatedByCharactersInSet:invalidChars];
NSString *resultString = [components componentsJoinedByString:#""];
Many ways to do it, here is one using character sets:
unichar ch = '5';
BOOL isLetter = [[NSCharacterSet letterCharacterSet] characterIsMember: ch];
BOOL isDigit = [[NSCharacterSet decimalDigitCharacterSet] characterIsMember: ch];
NSLog(#"'%C' is a letter: %d or a digit %d", ch, isLetter, isDigit);
You can use the C functions declared in ctype.h (included by default with Foundation). Be careful with multibyte characters though. Check the man pages.
char c = 'a';
if (isdigit(c)) {
/* ... */
} else if (isalpha(c)) {
/* ... */
}
/* or */
if (isalnum(c))
/* ... */
Checking if a character is a (arabic) number:
NSString* text = [...];
unichar character = [text characterAtIndex:0];
BOOL isNumber = (character >= '0' && character <= '9');
It would be different if you would to know other numeric characters (indian numbers, japanese numbers etc.)
Whether character is a letter depends on what you mean by letter. ASCII letters? Unicode letters?
I'm not too familiar with obj-c, but this sounds like something that can be achieved using a regex pattern.
I did some searching and found this:
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html
Try running a regex of "[0-9]" on each character to determine if it is a number.
Save the number to a temporary array, your array should end up with only the numbers.
I would type out the code...but as I said before, I'm not familiar with obj-c. I hope this helps though.
You can check them by comparing the ASCII value for number (0-9 ASCII ranged from 48-57) .. Also you can use NSScanner in Objective C to test for int or a char.

Help with NSString of int's to NSString of ASCII characters?

I have implemented some code to convert a NSString of "text" to an NSString of (ASCII) ints, like so:
#"Hello" is converted to #"72 101 108 108 111"
However, I am having quite a bit of difficulty doing the opposite. Starting with a string of ints (with the spaces) and converting back to the plain string of text.
What I need: #"72 101 108 108 111" must be converted to #"Hello"
I have tried breaking up the input string into an int array, iterating through it, and using repeatedly the following:
[NSString stringWithFormat:#"%c", decCharArray[i]]
However, the problem with that is that it parses each particular digit into ASCII, converting the 7, the 2, the space, the 1, etc.
Thanks a ton in advance.
Sounds like you have the right approach. Try using [string componentsSeparatedByString:#" "] to split the string at the spaces. Then you can convert each of those to numbers, and back into strings.
There is no real magic on it. Since you'll be using ASCII, to convert an int
to a char all you have to do is an assignment, as you may already know:
char a = 65; /* a contains 'A' */
NSString has a very convenient method componentsSeparatedByString: that will
return an array of strings containing your numbers, and you can get an int
from a string with the intValue method. Thus, all you have to do is to split
the string and iterate through the components assigning their int value to a
char array. Here is an example function that does that:
NSString *
TextFromAsciiCodesString (NSString *string)
{
NSArray *components = [string componentsSeparatedByString:#" "];
NSUInteger len = [components count];
char new_str[len+1];
int i;
for (i = 0; i < len; ++i)
new_str[i] = [[components objectAtIndex:i] intValue];
new_str[i] = '\0';
return [NSString stringWithCString:new_str
encoding:NSASCIIStringEncoding];
}
And a simple use of it, with your "Hello" example:
NSString *string = #"72 101 108 108 111";
NSLog(#"%#", TextFromAsciiCodesString(string));
Actually, it's a bit different as your example was "Hell^K" :-)
You can also trying using NSString's enumerateSubstringsInRange:options:usingBlock:.
Usage
NSString * hello = #"72 101 108 108 111";
NSMutableString * result = [NSMutableString string];
[hello enumerateSubstringsInRange:NSMakeRange(0, [data length])
options:NSStringEnumerationByWords
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[result appendString:[NSString stringWithFormat:#"%c", [substring intValue]]];
}];
NSLog(#"%#", result);

Convert hex data string to NSData in Objective C (cocoa)

fairly new iPhone developer here. Building an app to send RS232 commands to a device expecting them over a TCP/IP socket connection. I've got the comms part down, and can send ASCII commands fine. It's the hex code commands I'm having trouble with.
So lets say I have the following hex data to send (in this format):
\x1C\x02d\x00\x00\x00\xFF\x7F
How do I convert this into an NSData object, which my send method expects?
Obviously this does not work for this hex data (but does for standard ascii commands):
NSString *commandascii;
NSData *commandToSend;
commandascii = #"\x1C\x02d\x00\x00\x00\xFF\x7F";
commandToSend = [commandascii dataUsingEncoding:NSStringEncoding];
For a start, some of the \x hex codes are escape characters, and I get an "input conversion stopped..." warning when compiling in XCode. And NSStringEncoding obviously isn't right for this hex string either.
So the first problem is how to store this hex string I guess, then how to convert to NSData.
Any ideas?
Code for hex in NSStrings like "00 05 22 1C EA 01 00 FF". 'command' is the hex NSString.
command = [command stringByReplacingOccurrencesOfString:#" " withString:#""];
NSMutableData *commandToSend= [[NSMutableData alloc] init];
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
for (int i = 0; i < ([command length] / 2); i++) {
byte_chars[0] = [command characterAtIndex:i*2];
byte_chars[1] = [command characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[commandToSend appendBytes:&whole_byte length:1];
}
NSLog(#"%#", commandToSend);
Here's an example decoder implemented on a category on NSString.
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
unsigned char strToChar (char a, char b)
{
char encoder[3] = {'\0','\0','\0'};
encoder[0] = a;
encoder[1] = b;
return (char) strtol(encoder,NULL,16);
}
#interface NSString (NSStringExtensions)
- (NSData *) decodeFromHexidecimal;
#end
#implementation NSString (NSStringExtensions)
- (NSData *) decodeFromHexidecimal;
{
const char * bytes = [self cStringUsingEncoding: NSUTF8StringEncoding];
NSUInteger length = strlen(bytes);
unsigned char * r = (unsigned char *) malloc(length / 2 + 1);
unsigned char * index = r;
while ((*bytes) && (*(bytes +1))) {
*index = strToChar(*bytes, *(bytes +1));
index++;
bytes+=2;
}
*index = '\0';
NSData * result = [NSData dataWithBytes: r length: length / 2];
free(r);
return result;
}
#end
If you can hard code the hex data:
const char bytes[] = "\x00\x12\x45\xAB";
size_t length = (sizeof bytes) - 1; //string literals have implicit trailing '\0'
NSData *data = [NSData dataWithBytes:bytes length:length];
If your code must interpret the hex string (assuming the hex string is in a variable called inputData and lengthOfInputData is the length of inputData):
#define HexCharToNybble(x) ((char)((x > '9') ? tolower(x) - 'a' + 10 : x - '0') & 0xF)
int i;
NSMutableData *data = [NSMutableData data];
for (i = 0; i < lengthOfInputData;)
{
char byteToAppend;
if (i < (lengthOfInputData - 3) &&
inputData[i+0] == '\\' &&
inputData[i+1] == 'x' &&
isxdigit(inputData[i+2]) &&
isxdigit(inputData[i+3]))
{
byteToAppend = HexCharToNybble(inputData[i+2]) << 4 + HexCharToNybble(input[i+3]);
i += 4;
}
else
{
byteToAppend = inputData[i];
i += 1;
}
[data appendBytes:&byteToAppend length:1];
}
This is an old topic, but I'd like to add some remarks.
• Scanning a string with [NSString characterAtIndex] is not very efficient.
Get the C string in UTF8, then scan it using a *char++ is much faster.
• It's better to allocate NSMutableData with capacity, to avoid time consuming block resizing. I think NSData is even better ( see next point )
• Instead of create NSData using malloc, then [NSData dataWithBytes] and finally free, use malloc, and [NSData dataWithBytesNoCopy:length:freeWhenDone:]
It also avoids memory operation ( reallocate, copy, free ). The freeWhenDone boolean tells the NSData to take ownership of the memory block, and free it when it will be released.
• Here is the function I have to convert hex strings to bytes blocks. There is not much error checking on input string, but the allocation is tested.
The formatting of the input string ( like remove 0x, spaces and punctuation marks ) is better out of the conversion function.
Why would we lose some time doing extra processing if we are sure the input is OK.
+(NSData*)bytesStringToData:(NSString*)bytesString
{
if (!bytesString || !bytesString.length) return NULL;
// Get the c string
const char *scanner=[bytesString cStringUsingEncoding:NSUTF8StringEncoding];
char twoChars[3]={0,0,0};
long bytesBlockSize = formattedBytesString.length/2;
long counter = bytesBlockSize;
Byte *bytesBlock = malloc(bytesBlockSize);
if (!bytesBlock) return NULL;
Byte *writer = bytesBlock;
while (counter--) {
twoChars[0]=*scanner++;
twoChars[1]=*scanner++;
*writer++ = strtol(twoChars, NULL, 16);
}
return[NSData dataWithBytesNoCopy:bytesBlock length:bytesBlockSize freeWhenDone:YES];
}
If I want to hard-code the bytes, I do something like this:
enum { numCommandBytes = 8 };
static const unsigned char commandBytes[numCommandBytes] = { 0x1c, 0x02, 'd', 0x0, 0x0, 0x0, 0xff, 0x7f };
If you're obtaining these backslash-escaped bytes at run time, try the strunvis function.
Obviously this does not work for this hex data (but does for standard ascii commands):
NSString *commandascii;
NSData *commandToSend;
commandascii = #"\x1C\x02d\x00\x00\x00\xFF\x7F";
commandToSend = [commandascii dataUsingEncoding:NSStringEncoding];
For a start, some of the \x hex codes are escape characters, and I get an "input conversion stopped..." warning when compiling in XCode. And NSStringEncoding obviously isn't right for this hex string either.
First, it's Xcode, with a lowercase c.
Second, NSStringEncoding is a type, not an encoding identifier. That code shouldn't compile at all.
More to the point, backslash-escaping is not an encoding; in fact, it's largely independent of encoding. The backslash and 'x' are characters, not bytes, which means that they must be encoded to (and decoded from) bytes, which is the job of an encoding.
Another way to do it.
-(NSData *) dataFromHexString:(NSString *) hexstr
{
NSMutableData *data = [[NSMutableData alloc] init];
NSString *inputStr = [hexstr uppercaseString];
NSString *hexChars = #"0123456789ABCDEF";
Byte b1,b2;
b1 = 255;
b2 = 255;
for (int i=0; i<hexstr.length; i++) {
NSString *subStr = [inputStr substringWithRange:NSMakeRange(i, 1)];
NSRange loc = [hexChars rangeOfString:subStr];
if (loc.location == NSNotFound) continue;
if (255 == b1) {
b1 = (Byte)loc.location;
}else {
b2 = (Byte)loc.location;
//Appending the Byte to NSData
Byte *bytes = malloc(sizeof(Byte) *1);
bytes[0] = ((b1<<4) & 0xf0) | (b2 & 0x0f);
[data appendBytes:bytes length:1];
b1 = b2 = 255;
}
}
return data;
}
-(NSData*) convertToByteArray:(NSString*) command {
if (command == nil || command.length == 0) return nil;
NSString *command1 = command;
if(command1.length%2 != 0) {
// to handle odd bytes like 1000 decimal = 3E8 with is of length = 3
command1 = [NSString stringWithFormat:#"0%#",command1];
}
NSUInteger length = command1.length/2 ;
NSMutableData *commandToSend = [[NSMutableData alloc] initWithLength:length];
char byte_chars[3] = {'\0','\0','\0'};
unsigned char whole_byte;
for (int i=0; i<length; i++) {
byte_chars[0] = [command1 characterAtIndex:i*2];
byte_chars[1] = [command1 characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[commandToSend appendBytes:&whole_byte length:1];
}
NSRange commandRange = NSMakeRange(commandToSend.length - length, length);
NSData *result = [commandToSend subdataWithRange:commandRange];
return result;
}
I know this is a very old thread, but there is an encoding scheme in Objective C that can easily convert your string of hex codes into ASCII characters.
1) remove the \x from the string and with out keeping spaces in the string just convert the string to NSData using :
[[NSData alloc] initWithData:[stringToBeConverted dataUsingEncoding:NSASCIIStringEncoding]];
Hex data is just bytes in memory, you think of it as a string because that's how you see it but they could represent anything.
Try: (typed in the browser, may contain errors)
NSMutableData *hexData = [[NSMutableData alloc] init];
[hexData appendBytes: 0x1C];
[hexData appendBytes: 0x02D];
etc...