How does one find a '.' in a string object in Object-C - objective-c

I am working on getting a simple calculator working as part of my adventure to learning Object-C and iOS development.
In Object-C using NSString, how does one look for a period in a string?
Based on the comments this is what I got so far.
NSString * tmp = [display text];
NSLog(#"%#", tmp); // Shows the number on the display correctly
int x = [tmp rangeOfString:#"."].location;
NSLog(#"%i", x); // Shows some random signed number
if (x < 0) {
[display setText:[[display text] stringByAppendingFormat:#"."]];
}
It is still not working :(

NSRange is a straight-up struct...
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
int x = [#"hello.there.ok" rangeOfString:#"."].location;
printf("x is %d\n",x);
prints 5.
and here is a whole program:
int main(int argc, char *argv[])
{
NSString *ht = #"This is a string";
int r1 = [ht rangeOfString:#"is"].location;
int r2 = [ht rangeOfString:#"is a"].location;
int r3 = [ht rangeOfString:#"isnt"].location;
NSLog(#"r1=%d, r2=%d, r3=%d, that's all\n",r1,r2,r3);
}
which prints:
Program loaded.
run
[Switching to process 21098]
Running…
2011-01-14 20:45:25.192 DELETEME[21098:a0b] r1=2, r2=5, r3=-1, that's all
running this in XCode, Mac OS... should be straightahead!

Related

How to change mouse settings programmatically in macOS using IOKit

The functions IOHIDGetAccelerationWithKey and IOHIDSetAccelerationWithKey are deprecated since macOS 10.12, therefore I am trying to implement the same using other IO*-methods.
I have never worked with IOKit, thus, all I can do is google for functions and try to get it to work.
Now I found this: Can't edit IORegistryEntry which has an example of how to change TrackpadThreeFingerSwipe property, however it is using a function which is not defined for me: getEVSHandle. Googling for it reveals only that it should be Found in the MachineSettings framework, however I can't seem to add any "MachineSettings" framework in Xcode 11.
What should I do? Current code is like:
#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDLib.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSInteger value = -65536;
CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, kCFNumberNSIntegerType, &value);
CFMutableDictionaryRef propertyDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, NULL, NULL);
CFDictionarySetValue(propertyDict, #"HIDMouseAcceleration", number);
io_connect_t connect = getEVSHandle(); // ???
if (!connect)
{
NSLog(#"Unable to get EVS handle");
}
res = IOConnectSetCFProperties(connect, propertyDict);
if (res != KERN_SUCCESS)
{
NSLog(#"Failed to set mouse acceleration (%d)", res);
}
IOObjectRelease(service);
CFRelease(propertyDict);
}
return 0;
}
The following works (tested with Xcode 11.2 / macOS 10.15)
#import <Foundation/Foundation.h>
#import <IOKit/hidsystem/IOHIDLib.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
io_service_t service = IORegistryEntryFromPath(kIOMasterPortDefault,
kIOServicePlane ":/IOResources/IOHIDSystem");
NSDictionary *parameters = (__bridge NSDictionary *)IORegistryEntryCreateCFProperty(service,
CFSTR(kIOHIDParametersKey), kCFAllocatorDefault, kNilOptions);
NSLog(#"%#", parameters);
NSMutableDictionary *newParameters = [parameters mutableCopy];
newParameters[#"HIDMouseAcceleration"] = #(12345);
kern_return_t result = IORegistryEntrySetCFProperty(service,
CFSTR(kIOHIDParametersKey), (__bridge CFDictionaryRef)newParameters);
NSLog(kIOReturnSuccess == result ? #"Updated" : #"Failed");
IOObjectRelease(service);
}
return 0;
}

Using NSUInteger Input to insertObject:___ atIndex:___

I'm trying to create a simple commandline tic-tac-toe game using an NSMutableArray.
Created a class called "Board" with the method "getPosition"
(I'm assuming this is the best way to get a user input)
I'm asking for position, then casting from int to NSUInteger)
#import "Board.h"
#implementation Board
-(void)getPosition;
{
int enteredPosition;
scanf("%i", &enteredPosition);
NSUInteger nsEnteredPosition = (NSUInteger ) enteredPosition;
NSLog(#"Position = %lu", (unsigned long)nsEnteredPosition);
}
#import <Foundation/Foundation.h>
#import "Board.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSString *currentPlayer;
NSMutableArray *gameBoard=[[NSMutableArray alloc] initWithCapacity:9];
for(int i; i<=2; i++)
{
if(i %2)
{
currentPlayer=#"X";
}
else
{
currentPlayer=#"O";
}
NSLog(#"Player %#, select an open spot 1 - 9 on the board", currentPlayer);
Board *currentPosition = [[Board alloc] init];
[currentPosition getPosition];
[gameBoard insertObject:currentPlayer atIndex:currentPosition]; //this is where i have a problem
}
As I understand it atIndex requires an NSUInteger parameter, but I'm receiving the error message:
"Incompatible pointer to integer conversion sending 'Board *_strong"
to parameter of type 'NSUInteger' (aka 'unassigned long')
You're using currentPosition as your index which is a Board object. Perhaps [currentPosition getPosition] is supposed to return an NSUInteger. If so, try rewriting the last portion of your code like this:
Board *theBoard = [[Board alloc] init];
NSUInteger currentPosition = [theBoard getPosition];
[gameBoard insertObject:currentPlayer atIndex:currentPosition]; //this is where i have a problem

Why do i get "program received signal: "EXC_BAD_ACCESS" on NSString veriable

I just recently started learning Objective C, when i run the next program i get error
"program received signal: "EXC_BAD_ACCESS"
For the code line
if([*userChoice isEqualToString:#"yes"])
The full code is:
void initGame (void);
void restartGame(void);
void toGoOn(char *playerChoice);
int guess=-1;
int from=-1;
int to=-1;
bool playStatus=true;
bool gameStatus=true;
int answer=-1;
NSString *userChoice[10];
//if true the game is on
int main (int argc, const char * argv[])
{
#autoreleasepool {
GuessManager *game=GUESS;
NSLog(#"Hello, lets play");
NSLog(#"Please provide a positive range in which you would like to play");
do{
initGame();
[game setnumberToGuess:from :to];
do {
printf("Make you guess:");
scanf("%d", &guess);
[game setUserGuess:guess];
[game checkUserGuess];
if([game getDidIgetIt])
{
playStatus=false;
}
else
{
playStatus=true;
}
} while (playStatus);
restartGame();
}while(gameStatus);
printf("Thanks For Playing PanGogi Games! GoodBye");
}
return 0;
}
void initGame (void)
{
printf("from:");
scanf("%d",&from);
printf("to:");
scanf("%d",&to);
}
void restartGame(void)
{
printf("Would you like to continue?(yes/no)");
scanf("%s",&userChoice);
//scanf("%d",&answer);
// if(answer==1)
if([*userChoice isEqualToString:#"yes"])
{
gameStatus=true;
}
else
{
gameStatus=false;
}
}
I understand that its related to the NSString variable userChoice and how its used in
the if, but what i cant find is what am i doing wrong.
Please help :)
You have 3 errors in the code
1) I think you are getting confused with NSString and C style char array... You just need to use single NSString object to save multi character data..
NSString *userChoice;
2) Since you want to input data using scanf, you need a C style character array. scanf won't work with NSString types.
char tempArray[10];
int count = scanf("%s",&tempArray);
userChoice = [NSString stringWithBytes:tempArray length:count encoding: NSUTF8StringEncoding];
3) Now you can use NSString directly.. No need for pointer like syntax
if( [userChoice isEqualToString: #"yes"]){
.....
.....
}
You're using NSString as if it was char. It's not. It's a class that represents a string.
The scanf function is a C function and needs a char array, not an NSString.
char str[80];
scanf("%s", &str);
You can initialize an NSString object with a char array like this:
NSString *userChoice = [NSString stringWithCString:str encoding:NSASCIIEncoding];
And compare like this:
if ([userChoice isEqualToString:#"yes"]) {
...
} else {
...
}

Quick way to jumble the order of an NSString?

Does anyone know of an existing way to change the order of an existing NSString or NSMutableString's characters? I have a workaround in mind anyway but it would be great if there was an existing method for it.
For example, given the string #"HORSE", a method which would return #"ORSEH", #"SORHE", #"ROHES", etc?
Consider this code:
.h File:
#interface NSString (Scrambling)
+ (NSString *)scrambleString:(NSString *)toScramble;
#end
.m File:
#implementation NSString (Scrambling)
+ (NSString *)scrambleString:(NSString *)toScramble {
for (int i = 0; i < [toScramble length] * 15; i ++) {
int pos = arc4random() % [toScramble length];
int pos2 = arc4random() % ([toScramble length] - 1);
char ch = [toScramble characterAtIndex:pos];
NSString *before = [toScramble substringToIndex:pos];
NSString *after = [toScramble substringFromIndex:pos + 1];
NSString *temp = [before stringByAppendingString:after];
before = [temp substringToIndex:pos2];
after = [temp substringFromIndex:pos2];
toScramble = [before stringByAppendingFormat:#"%c%#", ch, after];
}
return toScramble;
}
#end
Not the most beautiful code or execution, but gets the job done. There's probably a (const char *) way to do this, but this works fine for me. A quick test shows a 0.001021 second length for execution on my Mac.
Usage:
NSString *scrambled = [NSString scrambleString:otherString];
Code adapted from another language / pseudocode
You can use Durstenfeld's variation of the Fisher-Yates Shuffle.
For a very long string, you could save a lot of CPU time and allocations by copying the unichars to a unichar buffer, then performing the transform using a c or c++ approach to swap characters. Note that the UTF8String is not the buffer you want to take, nor should you mutate it. Then create (or set) a new NSString from the shuffled buffer.
More info on the Fisher Yates algo and C and C++ implementations can be found here.

Calling a C function from Objective-C with string array

I'm trying to call a simple tutorial C function from Objective-C and I can't figure out how to split up the arguments being passed, which is two strings.
int cFunction(int argc, char **argv)
{
int i;
printf("argc = %d\n", argc);
for (i = 0; i < argc; i++) {
printf("argv[%d] = \"%s\"\n", i, argv[i]);
}
return 0;
}
I've tried cFunction(3, "string1 string2"), cFunction(3, "string1", "string2"), and cFunction(3, args), with args being an NSArray composed of [textField1 stringValue] and [textField2 stringValue]
I get EXC_BAD_ACCESS when trying to printf argv[i]. I've also tried passing 2 as the value of argc.
How should this be called? Thanks
In this function parameter list, argv is a pointer to a C string array (char **).
Using the Objective-C NSString or NSArray type isn't possible with this function, First, convert each string using -(const char *)cStringUsingEncoding:(NSStringEncoding)encoding;, and store them into a C array of strings.
// myString is "arg1"
// mySecondString is "arg2"
char *cString = [myString
cStringUsingEncoding:NSUTF8StringEncoding];
char *cSecondString = [mySecondString
cStringUsingEncoding:NSUTF8StringEncoding];
char *myStrings[2] = { cString, cSecondString };
int returnCode = cFunction(2, myStrings);
This should work.