Why does the Objective-C Compiler return a "y" as a "0" but then skips over the "if input==0" section? - objective-c

int side1test;
NSLog(#"Is your triangle setup as in an Angle-Side-Angle? (Use 1 for Yes and 0 for No.)");
scanf(" %i", &side1test);
Returns "0" when the user enters a "y." However,
if (side1test != 1 && side1test != 0){
NSLog(#"Please use a '1' for YES and '0' for NO.");
}
Then does not catch.
The program drops into my else clause, and outputs all the NSLogs, skipping the scanf() commands, taking each of them as "0." What is wrong here?

I'm not a c++ dev but from googling that function returns the number of valid matches. If it returns 0 you should assume invalid input. side1test has not been set which is why it's 0.
Your code should probably be:--
int side1test;
NSLog(#"Is your triangle setup as in an Angle-Side-Angle? (Use 1 for Yes and 0 for No.)");
int result = 0;
while (result==0)
{
result =scanf(" %i", &side1test);
}
if (side1test != 1 && side1test != 0){
NSLog(#"Please use a '1' for YES and '0' for NO.");
}

Related

how do i correctly use >= and <= in code?

I have tried many thing involving this, >=, >==, =>, ==>.i can not find one that works. hey all return either primary expression needed or expected initializer before '>'. I am creating a IR receiver latch switch and thus have to create parameters for the code because the receiver is not constant in all conditions. Full code below. Any suggestions to fix the code please reply and don't DM me. Thank you.
code:
int LEDState = 0;
int LEDPin = 8;
int dt = 100;
int recieverOld ==> 500 and recieverOld ==< 2000;
int recieverNew;
int recieverPin = 12;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(LEDPin, OUTPUT);
pinMode(recieverPin, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
recieverNew = digitalRead(recieverPin);
if((recieverOld >== 0 && recieverOld <== 10) && (recieverNew >== 500 && recieverNew <== 2000) {
if(LEDState == 0) {
digitalWrite(LEDPin, HIGH);
LEDState = 1;
}
}
recieverOld = recieverNew;
delay(dt);
}
error:
expected initializer before '==' token
if one = used line 4 and related, return error expected primary-expression before '>' token
if > before = line 4 and related, return error expected initializer before '>=' token
Any solutions or suggestions welcome.
TL;DR
Operators that do no exist, and that you should NOT use:
==>, ==<, >==, <==
Operators that works and you can use them:
>= - MORE THAN OR EQUAL, compare operator, for example X >= 5
<= - LESS THAN OR EQUAL, compare operator, for example X <= 5
> - MORE THAN, compare operator, for example X > 5
< - LESS THAN, compare operator, for example X < 5
== - compare operator, when you want to compare values of the variables if they have the same value, for example X == 5, Y == X, 10 == 7
=== - equality operator, similar to compare operator ==, but aditionally checks the type of a variable. for example X === Y, '10' === 10
= - assign operator, when you want to assign something to the variable, for example X = 5
<> OR != - NOT EQUAL, compare operator, for example X != 5, Y <> 10
!== - similar to != or <>, but also checks the type of a value. For example 10 !== '10', and will return opposite result of the equality operator ===

Check for consecutive value in Map?

I'm creating a chat app and don't want to display the user avatar over and over if a user sends multiple messages consecutively.
The user messages are stored in a Map, where the newest message has the index 0.
To check if a message at an index is sent by the same person as the message before, I use the following method:
bool _sameUser () {
if (index > 0 && map != null && map[index + 1] != null && map[index + 1]['fromUser’] == map[index][‘fromUser’]) {
return true;
} else {
return false;
}
}
However, this doesn't work for the newest message or if there are more than two messages from the same user.
How I can rewrite the conditional so it works as intended?
Thanks!
UPDATE:
After try #Marcel answer and test more I find another issue maybe cause this.
map[index + 1] != null is not true even when message 2 is send. Is only true after message 3 is send.
I test with conditional in function:
if (map[index + 1] != null) {
print('!=null');
}
There's no reason your code shouldn't work for the index 0 except you test index > 0.
By removing that, it should work fine:
bool _sameUser () {
assert(index >= 0);
assert(map != null);
return map[index + 1] != null && map[index + 1]['fromUser'] == map[index]['fromUser'];
}
Because I assumed, the index should never be smaller than 0 and the map should never be null, I moved some of the condition code to assert statements.
Also, because your if-expression is a boolean, you can just return it directly.

Use variables as case constants in swich statement

I'm trying to use a variable as the case match, however I get "Expression is not an integer in Objective-C.
Is it possible to use variable in switches in this manner?
int count = [array count];
switch ([number to check]) {
case 0:
//first statement
break;
case 1 ... (count -1):
//somewhere between 1 and the next to last statement
//Basically the middle
break;
case count:
//Last statement
default:
break;
}
Objective-C (and C) switch only supports a single primitive constant value for each case statement (or a range as pointed out in the answer by TwoStraws). You would be much better off writing your code using if/else:
if ([number to check] == 0) {
} else if ([number to check] >= 1 && [number to check] < count) {
} else if ([number to check] == count) {
} else {
}
Objective-C's switch statement does support ranges of values as you've seen, but doesn't support variable matches I'm afraid.
So, the below code is valid because I've used exact integers:
int numberOfKittens = 12;
NSString *kittenDescription;
switch (numberOfKittens) {
case 0 ... 5:
kittenDescription = #"Need more kittens";
break;
case 6 ... 10:
kittenDescription = #"That's a good number of kittens.";
break;
case 11 ... 20:
kittenDescription = #"Are you sure you can handle that many kittens?";
break;
default:
kittenDescription = #"You must really love kittens!";
}
…but trying to put a variable in place of any of those will fail.
If this is something you desperately want, consider using Swift because it has a much more expressive switch matching system. Here's that same code in Swift, now with a variable being used to match a case:
let upperLimit = 20
let numberOfKittens = 19
var kittenDescription = ""
switch (numberOfKittens) {
case 0 ... 5:
kittenDescription = "Need more kittens"
case 6 ... 10:
kittenDescription = "That's a good number of kittens."
case 11 ... upperLimit:
kittenDescription = "Are you sure you can handle that many kittens?"
default:
kittenDescription = "You must really love kittens!"
}

if statement gone wrong -xcode

Guys what am I doing wrong?
if (numberstring.intValue <=15) {
rankLabel.text = #"A1";
}
else if (numberstring.intValue >16 && <=40){
rankLabel.text = #"A2";
}
I get an error on the "<=40" ..
You missed off a variable reference:
if (numberstring.intValue <=15) {
rankLabel.text = #"A1";
} // vv here vv
else if (numberstring.intValue >16 && numberstring.intValue <= 40){
rankLabel.text = #"A2";
}
As an optional extra, it looks like numberstring is an NSString object, which you are repeatedly converting to an integer in order to test various ranges. That operation is quite expensive, so you are better off doing the conversion once:
int value = [numberstring intValue];
if (value <=15) {
rankLabel.text = #"A1";
}
else if (value >16 && value <= 40){
rankLabel.text = #"A2";
}
Also note that the intValue method is not a property so I would avoid using the Objective-C 2.0 dot syntax to access it and use the normal method calling mechanism.
The && operator links two clauses together. However, each clause is independent, so each one has to be syntactically correct on its own if the other was removed. If you apply this rule to your condition, you can see that "<=40" is not syntactically correct on its own. Thus you need to reference the value being compared, as follows:
if (numberstring.intValue > 16 &&
numberstring.intValue <= 40) // this is syntactically correct on its own

Comparing multiple values at once using &&

I have this code:
if ((total == (total1 && total2 && total3)))
{
[scrollview.contentOffset = CGPointMake (0,0)];
}
here is what it's something like on button action:
if (sender.tag == 1)
{
total1 = 10;
}
if (sender.tag == 2)
{
total2 = 20;
}
if (sender.tag == 3)
{
total3 = 30;
}
I am trying to go back to the start page of the scroll view if the user clicked the three correct buttons (similar to a password key).
Does the logical operator && work well in Objective-C, and did I use it right?
if ((total == (total1 && total2 && total3)))
You cannot do that. You have to explicitly compare each separately.
if ((total == total1) && (total == total2) && (total == total3)))
But that leaves the question of how total can be equal to all the three simultaneously though.
In your code:
if ((total == (total1 && total2 && total3)))
{
[scrollview.contentOffset = CGPointMake (0,0)];
}
When the if expression is evaluated, (total1 && total2 && total3) is evaluated first. And that can be either YES or NO (true or false if you prefer), or (0 or 1).
So your code is equivalent to the following:
BOOL allVariablesAreNotZero = total1 && total2 && total3;
if (total == allVariablesAreNotZero)
{
[scrollview.contentOffset = CGPointMake (0,0)];
}
Edit after the question was better explained
Make your buttons perform the following action when pressed:
- (void)buttonClicked:(id)sender
{
UIButton *button = (UIButton *)sender;
buttonsCombination = buttonsCombination | (1 << button.tag);
}
Where buttonsCombination is an NSUInteger. Then use the following test to see if the buttons that were pressed are the correct ones (I am doing this with three buttons, but you guess the idea)
NSUInteger correctCombination = (1 << button1) | (1 << button2) | (1 << button3)
if (buttonsCombination == correctCombination) {
// The combination is correct
} else {
// The combination is incorrect
}
buttonsCombination = 0;
Finally, note that this works because there are enough bits in a NSUInteger for 30 buttons.
Here I used bitwise operators | and <<.
What your current code is essentially saying is "if total is 'true' and total1, total2, and total3 are also all nonzero or if total is zero and total1, total2, and total3 are also all zero, then do something".
The && you have there is doing a logical/boolean comparison. It treats its arguments as being either true or false, and returns true if both arguments evaluate to true and false in any other case. The == compares the value of total with the true or false value that was obtained from your && expressions. That is probably not what you want here.
It seems like probably what you want to be saying is "if total is equal to the sum of total1, total2, and total3, then do something". Assuming this is the case, you would do:
if (total == (total1 + total2 + total3)) {
[scrollview.contentOffset = CGPointMake (0,0)];
}
Trying to determine what you mean by your comment on two other answers "i tried it but it executes the codes when i started to run the app" maybe this is what you're trying to achieve:
/* all in your button handler */
switch(sender.tag)
{
case 1:
total1 = 10;
break;
case 2:
total2 = 20;
break;
case 3:
total3 = 30;
break;
default:
break; // other buttons are ignored
}
// check it latest click means the total is now correct
if((total1 + total2 + total3) == total)
{
[scrollview.contentOffset = CGPointMake (0,0)];
}
So you update any totalX's effected by the button click and then check the condition to reset the scrolling.