NSMutableString stringWithFormat - cocoa

I have java code that prepares a message for a MD5 munge
private static char[] jimsCopyRight = {
'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h',
't', ':', ' ', 0xa9, ' '};
which is used in
StringBuffer message = new StringBuffer();
message.append(name.toLowerCase());
message.append(new String(jimsCopyRight));
When I print out the message using
for(int i = 0; i < message.length(); i++){
System.out.println(" i = " + i + " char " + message.substring(i, i + 1) + " charAT " + message.charAt(i));
}
I get i = 14 char \251 charAT \251 and the message.toString is jimCopyright: \251
I need to construct a NSMutableString with the same characters.
Among the things I have tried
wDevCopyright = [NSString stringWithFormat:#"jimCopyright: %c ", 0xa9];
for(int i = 0; i < [message length]; i++){
NSLog(#"i = %d char %c %d", i, [message characterAtIndex:i], [message characterAtIndex:i]);
}
Which gives me i = 14 char © 169
Any help in getting the NSMutableString to be the same as the StringBuffer will be appreciated.
The problem is that when I munge the two strings in MD5 I get different results when I add the 0xa9. The prints are just for getting a look at the strings.
I'm thinking it has something to do with the char[] in Java and the construct of the NSMutableString. I do not believe they are the same values.
I have some C code and it declares the copyright as
#define jimsCopyRight "Copyright: � "
The Java MD5 and C MD5 of the copyright are the same.

The copyright symbol is what you wanted, right? According to your question, that's what you got. So what's the problem?
(This is why magic numbers are bad. I can't tell from your code alone what encoding's 0xa9 you wanted.)
If you're wondering why it says 169 instead of 251, it's because Java prints out the octal (base-8) character escape sequence, whereas %d in the C standard library, Core Foundation, and Foundation prints out the value as decimal (base-10). \251 is not the two hundred and fifty-first character. Use %o to print the value as octal, or %x to print it as hexadecimal (base-16). Or, use Calculator.app's Programming mode to convert 251 from octal to decimal.
BTW, you can use the %# format sequence and the NSUserName function to insert your username into the string, just like you did in the Java code. No need to hard-code it.

You’re missing an “s” in “jim[s]Copyright” in the Objective-C version.

Related

how can i display uint8 values on a oled display

I can compile the code but nothing shows
int main(void){
lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_set_contrast(0x00);
lcd_gotoxy(0,3);
lcd_puts((char*)&temperature);
lcd_gotoxy(1,2);
lcd_puts((char*)&humidity);
lcd_puts("Hello World");
}
You need to first convert the numerical data (e.g. uint8_t) to a string before you can display it.
E.g., the uint8_t value 123 is one byte, but to display it, it must be converted to a three-character/-byte string 1, 2, 3, i.e. the three chars 0x31, 0x32, 0x33.
For that, you can use the function itoa() ("integer to ascii") to copy the integer value to a char array you provide. Note that the char array must be big enough to hold any possible number-string, i.e. if your values are uint8_t's (range 0...255) the array must be at least three characters long.
To have a character array handled as a string in C(-libraries), you need an additional char to hold the string terminator '\0'.
Example:
char tempStr[3+1]; // One extra for terminator
// Clear tempStr and make sure there's always a string-terminating `\0` at the end
for ( uint8_t i = 0; i < sizeof(tempStr); i++ ) {
tempStr[i] = '\0';
}
itoa(temperature, tempStr, 10);
// Now we have the string representation of temperature in tempStr, followed by at least one '\0' to make it a valid string.
// For example:
// 1 --> [ '1', '\0', '\0', '\0' ]
// 255 --> [ '2', '5', '5', '\0' ]

Golang string end character

I'm a newbie in Golang, so I'm playing with some algorithms and i have a little problem.
In java for insert an end string in char array I can do like this:
String str = "Mr John Smith ";
char[] arr = str.toCharArray();
arr[12] = '\0';
But in Golang I'm trying like this:
str := []byte("Mr John Smith ")
str[12] = '\0'
But this code didn't work
That's not a valid syntax for a rune literal with a 0 value. You can use the hex escape sequence
str[12] = '\x00'
If you really need an octal value, it requires 3 digits
str[12] = '\000'
Or just assign a literal 0
str[12] = 0
You can see the valid rune literal escape sequences in the specification: https://golang.org/ref/spec#Rune_literals

C Program Strange Characters retrieved due to language setting on Windows

If the below code is compiled with UNICODE as compiler option, the GetComputerNameEx API returns junk characters.
Whereas if compiled without UNICODE option, the API returns truncated value of the hostname.
This issue is mostly seen with Asia-Pacific languages like Chinese, Japanese, Korean to name a few (i.e., non-English).
Can anyone throw some light on how this issue can be resolved.
# define INFO_SIZE 30
int main()
{
int ret;
TCHAR infoBuf[INFO_SIZE+1];
DWORD bufSize = (INFO_SIZE+1);
char *buf;
buf = (char *) malloc(INFO_SIZE+1);
if (!GetComputerNameEx((COMPUTER_NAME_FORMAT)1,
(LPTSTR)infoBuf, &bufSize))
{
printf("GetComputerNameEx failed (%d)\n", GetLastError());
return -1;
}
ret = wcstombs(buf, infoBuf, (INFO_SIZE+1));
buf[INFO_SIZE] = '\0';
return 0;
}
In the languages you mentioned, most characters are represented by more than one byte. This is because these languages have alphabets of much more than 256 characters. So you may need more than 30 bytes to encode 30 characters.
The usual pattern for calling a function like wcstombs goes like this: first get the amount of bytes required, then allocate a buffer, then convert the string.
(edit: that actually relies on a POSIX extension, which also got implemented on Windows)
size_t size = wcstombs(NULL, infoBuf, 0);
if (size == (size_t) -1) {
// some character can't be converted
}
char *buf = new char[size + 1];
size = wcstombs(buf, infoBuf, size + 1);

Converting Decimal to ASCII Character

I am trying to convert an decimal number to it's character equivalent. For example:
int j = 65 // The character equivalent would be 'A'.
Sorry, forgot to specify the language. I thought I did. I am using the Cocoa/Object-C. It is really frustrating. I have tried the following but it is still not converting correctly.
char_num1 = [working_text characterAtIndex:i]; // value = 65
char_num2 = [working_text characterAtIndex:i+1]; // value = 75
char_num3 = char_num1 + char_num2; // value = 140
char_str1 = [NSString stringWithFormat:#"%c",char_num3]; // mapped value = 229
char_str2 = [char_str2 stringByAppendingString:char_str1];
When char_num1 and char_num2 are added, I get the new ascii decimal value. However, when I try to convert the new decimal value to a character, I do not get the character that is mapped to char_num3.
Convert a character to a number in C:
int j = 'A';
Convert a number to a character in C:
char ch = 65;
Convert a character to a number in python:
j = ord('A')
Convert a number to a character in Python:
ch = chr(65)
Most languages have a 'char' function, so it would be Char(j)
I'm not sure what language you're asking about. In Java, this works:
int a = 'a';
It's quite often done with "chr" or "char", but some indication of the language / platform would be useful :-)
string k = Chr(j);

Best way to escape characters like newline and double-quote in NSString

Say I have an NSString (or NSMutableString) containing:
I said "Hello, world!".
He said "My name's not World."
What's the best way to turn that into:
I said \"Hello, world!\".\nHe said \"My name\'s not World.\"
Do I have to manually use -replaceOccurrencesOfString:withString: over and over to escape characters, or is there an easier way? These strings may contain characters from other alphabets/languages.
How is this done in other languages with other string classes?
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
I don't think there is any built-in method to "escape" a particular set of characters.
If the characters you wish to escape is well-defined, I'd probably stick with the simple solution you proposed, replacing the instances of the characters crudely.
Be warned that if your source string already has escaped characters in it, then you'll probably want to avoid "double-escaping" them. One way of achieving this would be to go through and "unescape" any escaped character strings in the string before then escaping them all again.
If you need to support a variable set of escaped characters, take a look at the NSScanner methods "scanUpToCharactersFromSet:intoString:" and "scanCharactersFromSet:intoString:". You could use these methods on NSScanner to cruise through a string, copying the parts from the "scanUpTo" section into a mutable string unchanged, and copying the parts from a particular character set only after escaping them.
This will escape double quotes in NSString:
NSString *escaped = [originalString stringByReplacingOccurrencesOfString:#"\"" withString:#"\\\""];
So you need to be careful and also escape the escape character...
I think in cases like these, it's useful to operate on a character at a time, either in UniChars or UTF8 bytes. If you're using UTF-8, then vis(3) will do most of the work for you (see below). Can I ask why you want to escape a single-quote within a double-quoted string? How are you planning to handle multi-byte characters? In the example below, I'm using UTF-8, encoding 8-bit characters using C-Style octal escapes. This can also be undone by unvis(3).
#import <Foundation/Foundation.h>
#import <vis.h>
#interface NSString (Escaping)
- (NSString *)stringByEscapingMetacharacters;
#end
#implementation NSString (Escaping)
- (NSString *)stringByEscapingMetacharacters
{
const char *UTF8Input = [self UTF8String];
char *UTF8Output = [[NSMutableData dataWithLength:strlen(UTF8Input) * 4 + 1 /* Worst case */] mutableBytes];
char ch, *och = UTF8Output;
while ((ch = *UTF8Input++))
if (ch == '\'' || ch == '\'' || ch == '\\' || ch == '"')
{
*och++ = '\\';
*och++ = ch;
}
else if (isascii(ch))
och = vis(och, ch, VIS_NL | VIS_TAB | VIS_CSTYLE, *UTF8Input);
else
och+= sprintf(och, "\\%03hho", ch);
return [NSString stringWithUTF8String:UTF8Output];
}
#end
int
main(int argc, const char *argv[])
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSLog(#"%#", [#"I said \"Hello, world!\".\nHe said \"My name's not World.\"" stringByEscapingMetacharacters]);
[pool drain];
return 0;
}
This is a snippet I have used in the past that works quite well:
- (NSString *)escapeString:(NSString *)aString
{
NSMutableString *returnString = [[NSMutableString alloc] init];
for(int i = 0; i < [aString length]; i++) {
unichar c = [aString characterAtIndex:i];
// if char needs to be escaped
if((('\\' == c) || ('\'' == c)) || ('"' == c)) {
[returnString appendFormat:#"\\%c", c];
} else {
[returnString appendFormat:#"%c", c];
}
}
return [returnString autorelease];
}
Do this:
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unencodedString,
NULL,
(CFStringRef)#"!*'();:#&=+$,/?%#[]",
kCFStringEncodingUTF8 );
Reference: http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/
You might even want to look into using a regex library (there are a lot of options available, RegexKit is a popular choice). It shouldn't be too hard to find a pre-written regex to escape strings that handles special cases like existing escaped characters.

Resources