Empty character in Objective-C - objective-c

I'm creating some code that will find a space between characters, and use the characters before the space and the ones after it. These characters are stored in a NSString. Here is what I have so far, however, it's not seeing the empty character.
NSString *tempTitle = self.title;
unsigned int indexOfSpace; // Holds the index of the character with the space
unsigned int titleLength = (unsigned int)self.title.length; // Holds the length of the title
for (unsigned int count = 0; count < titleLength; count++)
{
if ([tempTitle characterAtIndex:count] == "") // If the character at the index is blank, store this and stop
{
indexOfSpace == count;
}
else // Else, we keep on rollin'
{
NSLog(#"We're on character: %c", [tempTitle characterAtIndex:count]);
}
}
I've tried nil , empty string ("") and " " but no avail. Any ideas?

Your space character should be in single quotes, not double quotes. Single quotes get you the char type in C. (Double quotes create a string literal, which essentially functions as a char * and will never pass your comparison.)
-[NSString characterAtIndex:] returns a type unichar, which is an unsigned short, so you should be able to compare this directly to a space character ' ', if that's what you want to do.
Note that nil and empty string, are not useful here-- neither are actually characters, and in any case your string will never "contain" these.
You should see also the NSString methods for finding characters in strings directly, e.g. -[NSString rangeOfString:] and its cousins. That prevents you from writing the loop yourself, although those are unfortunately a little syntactically verbose.

Related

Alphanumeric in a string

I need help with fixing a code.
I need it to look at the first two characters of the subclass. If it is alphanumeric (letters and number) the subclassize=7; if both the first two characters are numeric
subclassize=4.
This is the code:
int startrentex=0;
int rentexsize=0;
//int totalsize=0;
int subclasssize=7;
//int descriptionsize=9;
int currentlength=[enteredText length];
if(appdata.appSettings.BarCodeStyle==0) {
if(currentlength>1){
NSString *str = [enteredText substringWithRange:NSMakeRange(1, 1)];
int testint=[str intValue];
if(![str isEqualToString:#"0"] && testint==0)
subclasssize=7;
else
subclasssize=4;
//a3fs12345hi there
//1B3456712345hi there
}
startrentex=subclasssize;
if(currentlength>subclasssize)
{
BOOL isspace=YES;
I need it to look at the first two characters of the subclass.
If you want to look at characters then use the NSString method - characterAtIndex:. This will return you a value of type unichar - the type of unicode characters in Objective-C.
Once you have your first two characters you can test them.
If it is alphanumeric (letters and number) the subclassize=7; if both the first two characters are numeric subclassize=4
To determine the class of a character you can use NSCharacterSet. This class provides standard sets of characters, e.g. + decimalDigitCharacterSet, and a method to test for membership - characterIsMember:.
With these classes and methods you should be able to quickly solve your problem. You will find full details of these classes and methods in Appleā€™s documentation.
HTH

Replacing character within cstring - getting bad access

Is it possible to replace a character from a c string after converting it from NSString via the UTF8string method?
For example take the code below. It is to format a string with particular rule.
- (NSString *)formatString:(NSString *)input {
if (input.length==0) {
return #"";
}
//code to determine rule
....
....
// substitute output format with input characters
if (rule) {
input = [input substringFromIndex:prefix.length];
char *string = (char *)[rule UTF8String];
int repCount = 0;
for (int i=0; i<rule.length; i++) {
if (string[i] == '#') {
if (repCount < input.length)
string[i] = [input characterAtIndex:repCount++];//bad access
else
string[i] = ' ';
}
}
NSMutableString *output = [NSMutableString stringWithCString:string encoding:NSUTF8StringEncoding];
...
... //do something with the output
return output;
} else {
return input;
}
}
Initially string[0] has '#' and it should get replaced with the character in the input. This is not happening.
In a word, NO. That buffer doesn't belong to you so leave it alone.
A couple of issues:
You are casting UTF8String, which returns a const char *, to char *. UTF8String is, by definition, returning a read-only string and you should use it as such. (You really should use casts sparingly, if at all. Certainly never use casts to override const qualifiers for variables.)
If you want to perform this C-string manipulation, you have to copy the string to your own buffer. For example, use getCString or getCharacters methods (but only after you've created a buffer to receive them, and remember to add a character for the NULL terminator).
By the way, you're also returning characterAtIndex, which is a unichar (which can be larger than 8-bits), and using it in your char * buffer (8-bits per character). I'd be wary about mixing and matching those without being very careful. It is best to pick one and stick with it (and unichar offers a little more tolerance for those non-8-bit characters).
Perhaps you check for this earlier, but you're setting string to be those characters after the prefix, and then proceed to check the next rule.length number of characters. But, as far as I can tell, you have no assurances that string actually has that many characters left in it. You should test for that, or else that will also cause problems.
Personally, I'd retire this whole C-string algorithm and employ the appropriate NSString and/or NSMutableString methods to do whatever replacement you wanted, e.g. stringByReplacingCharactersInRange, stringByReplacingOccurrencesOfString, or the equivalent NSMutableString methods, replaceCharactersInRange or replaceOccurrencesOfString.

Concatenating an int to a string in Objective-c

How do I concatenate the int length to the string I'm trying to slap into that array so it is "C10" given length == 10, of course. I see #"%d", intVarName way of doing it used else where. In Java I would of done "C" + length;. I am using the replaceObjectAtIndex method to replace the empty string, "", that I have previously populated the MSMutableArray "board" with. I am getting an error though when I add the #"C%d", length part at the end of that method (second to last line, above i++).
As part of my homework I have to randomly place "Chutes" (represented by a string of format, "C'length_of_chute'", in this first assignment they will always be of length 10 so it will simply be "C10") onto a game board represented by an array.
-(void)makeChutes: (int) length {// ??Change input to Negative number, Nvm.
//??Make argument number of Chutes ??randomly?? across the board.
for(int i = 0; i < length;){
int random = arc4random_uniform(101);
if ([[board objectAtIndex:random] isEqual:#""]) {
//[board insertObject:#"C%d",length atIndex:random];
[board replaceObjectAtIndex:random withObject:#"C%d",length];
i++;
}
}
}
Please ignore the extra and junk code in there, I left it in for context.
In Objective-C the stringWithFormat method is used for formatting strings:
NSString *formattedString = [NSString stringWithFormat:#"C%d", length];
[someArray insertObject:formattedString];
It's often easier to create your formatted string on a line of its own in Objective-C, since as you can see the call can be fairly verbose!

Why does this code have an array of 3 bytes to build a "whole byte"?

I found the following code on the internet, it converts NSString representations such as
#"00F04100002712" into an actual array of bytes. The code works and does generate the correct output; I just don't understand why there is char byte_chars[3] instead of char byte_chars[2] since only the first two positions are used in the code.
void hexStringToBytes(NSString *s, NSMutableData *data)
{
unsigned char whole_byte;
char byte_chars[3] = {'\0','\0','\0'};
int commandLength = (int)[s length];
// convert hex values to bytes
for (int i=0; i < commandLength/2; i++)
{
byte_chars[0] = [s characterAtIndex:i*2];
byte_chars[1] = [s characterAtIndex:i*2+1];
whole_byte = strtol(byte_chars, NULL, 16);
[data appendBytes:&whole_byte length:1];
}
}
I think it has something to do with the strtol function call but I am not sure what.
Can someone explain how and why this works?
C style strings have a terminating zero (aka null) character. An ASCII representation of an 8 bit byte in hexadecimal will be two characters plus that terminator.
Yes it does. strtol expects a "string". In C strings are null terminated. Thus the extra byte for the null.
C strings must be NULL (0) terminated. Since this is using a C string with a function expecting NULL terminated strings, the character array must have space for the NULL.
C strings must be NUL (0) terminated. The call to strtol function expects that.
You are messed up with C, C++ and Objective-C.
C++ and Obj-c uses full use of array. C++ creates an array of size + extra 1 space for NULL ('\0'). Obj-c has NSString class that is just a pointer, so NULL is not required.
In C you need to terminate an array of characters by NULL ('\0) and the last space is used from the allocated size. So if you write char str[10]; then you are allowed to use 9 characters and last one is automatically given to NULL.
In you code snippet you are using strtol, this is a C function which expects a C-char-array. there for last space is not used explicitly. NULL is occupying that place.

Objective-C NSString for loop with characterAtIndex

I'm trying to loop through a NSString, character by character, but I'm getting a EXC_BAD_ACCESS error. Do you have an idea how to do this right? I've been googling for hours now but can't figure it out.
Here is my code (.m):
self.textLength = [self.text length];
for (int position=0; position < self.textLength; position++) {
NSLog(#"%#", [self.text characterAtIndex:position]);
if ([[self.text characterAtIndex:position] isEqualToString:#"."]){
NSLog(#"it's a .");
}
}
Thanks a lot!
Characters are not object. characterAtIndex returns unichar, which is actually an integer type unsigned short. You need to use %C instead of %# in NSLog. Also character is not a NSString, so you can't send it isEqualToString. You need to use ch == '.' to compare ch against '.'.
unichar ch = [self.text characterAtIndex:position];
NSLog(#"%C", ch);
if (ch == '.') {} // single quotes around dot, not double quotes
Note that, 'a' is character, "a" is C string and #"a" is NSString. They all are different types.
When you are using %# with unichar ch in NSLog, it is trying to print an object from memory location ch which is invalid. Thus you are getting a EXC_BAD_ACCESS.
characterAtIndex: returns a unichar, so you should use NSLog(#"%C", ...) instead of #"%#".
You also cannot use isEqualToString for a unichar, just use == '.' is fine.
If you want to find the position of all '.'s, you can use rangeOfString. Refer to:
String Programming Guide: Searching, Comparing, and Sorting Strings
Position of a character in a NSString or NSMutableString
characterAtIndex: returns a unichar, which is declared as typedef unsigned short unichar; The format specifier you are using in your calls to NSLog are incorrect, you could just do NSLog(#"%u",[self.text characterAtIndex:position]); or NSLog(#"%C",[self.text characterAtIndex:position]); if you want the actual character to print out.
Also, as a result of unichar being defined the way that it is, it's not a string, so you cannot compare it to other strings. Try something like:
unichar textCharacter = '.';
if ([self.text characterAtPosition:position] == testCharacter) {
// do stuff
}
If you want to find the location of a character in a string you can use this:
NSUInteger position = [text rangeOfString:#"."].location;
if the character or text is not found you will get a NSNotFound:
if(position==NSNotFound)
NSLog(#"text not found!");