0

How does one compare a single integer to an array of ten integers to find if the single integer is contained within the array using C language? My apologies if original question was unclear, while swipe is equal to any number within the array I want to output PORTD=0b10000000. Thank you!

short a[10]={10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; //Array of accepted passwords.
short array[10];
int i;
for(i=0; i<10; i++){
    array[i]=a[i];
}

srand(clock());

while(1){
int swipe=rand() % 20; /* Simulated code read from card swipe, in this
                        * instance we used a random number between
                        * 1 and 20.*/
for(i=0; i<10; i++){    
    if(swipe == array[i]) {
        PORTD=0b10000000;
    } else {
        PORTD=0b00001000;
    } //If swiped code evaluates as one of the approved codes then set PORTD RD7 as high.
}

char Master=PORTDbits.RD7;

This seems to have solved it...thanks for all of your help!

for(i=0; i<10; i++){    
if(swipe == array[i]) {
    PORTD=0b10000000;
    break;
} else {
    PORTD=0b00001000;
    }
}
NewMC
  • 3
  • 1
  • 4
  • By the way, have you called `srand()`? – ryyker Mar 02 '16 at 19:59
  • i called srand but did not seem to make much difference as I'm currently getting different random variables each time the code runs through so I took it out. Thanks – NewMC Mar 02 '16 at 20:00
  • As you are calling `rand()` in a loop, you should call `srand()` once before to _[seed the pseudo random values](http://stackoverflow.com/a/16569330/645128)_. – ryyker Mar 02 '16 at 20:06
  • _is being seeded by system..._ I am not sure how, if this is an ANSI C call that it is being seeded by the system? Does it say this in the `xc8` compiler documentation then? – ryyker Mar 02 '16 at 20:15
  • "trying to compare a single value to an array" - this, I think, is the heart of the problem. What are you really trying to compare to? You can't compare a single value to an entire array, they are two different things. If you want to compare it to each element of the array, you need to code that explicitly (with another loop). – davmac Mar 02 '16 at 20:20
  • 1
    Read [ask] and provide a [mcve]. Your code has various problems. It is not even close to what you describe. – too honest for this site Mar 02 '16 at 20:33
  • @Olaf - I'm not sure how I could be more complete without printing my entire program? How to ask, here's my one sentence question: How does one compare a single integer to an array of ten integers to find if the single integer is contained within the array using C language? I'm sorry but I don't know how to be more clear. – NewMC Mar 02 '16 at 21:03
  • 5Did you even follow the links? What is not to be understood about **Minimal Complete and Verifyable**? And, no, posting the **whole** program code very likely contradicts the first requirement. – too honest for this site Mar 02 '16 at 21:05
  • I read your links and I'm not here to waste anyone's time, I don't understand if you're telling me you don't understand the question or what? Is my question not clear enough? I am generating a random code because I don't have an actual card reader or cards to swipe. – NewMC Mar 02 '16 at 21:13

4 Answers4

1

You need to test your swipe value against ALL ten values in your array of accepted passwords.

e.g. like below

for(i=0; i<10; i++)
  if(swipe == array[i]) {
    set a true flag (and maybe exit the for loop)
  }
Depending on the flag, set the output
pboedker
  • 523
  • 1
  • 3
  • 17
  • When I do this it evaluates as false even though I can see that swipe is one of the values in the array. PORTD=0b10000000 is the output that I want to see, this is setting one pin of a microcontroller to high (5V). – NewMC Mar 02 '16 at 20:42
0

if(swipe == a[i]). That invokes Undefined Behaviour as i is 10 and 10 is an out of bounds index. The valid indexes are from 0 to 9.

kaylum
  • 13,833
  • 2
  • 22
  • 31
  • Right. I suspect in this instance that `swipe` is being allocated storage just past the end of the array, which is why the comparison is always returning true - it's effectively comparing `swipe` with itself. Of course as you say the behaviour is undefined. – davmac Mar 02 '16 at 20:02
  • Oh wow, I thought I had written that statement correctly earlier and was getting the same output values but when I say i=0; i<9; i++ in my for loop I appear to be getting the correct values out now. Thanks so much!! – NewMC Mar 02 '16 at 20:03
  • @NewMC That's not the right solution. Leave that loop as it was. Otherwise it will leave one element of `array` unitialised. And the result will still be undefined behavior as `array[9]` would be unintialised. Instead, change the check to be `if(swipe == a[9])`. Or whatever index you are intending to compare. – kaylum Mar 02 '16 at 20:08
  • I thought I had written that statement correctly earlier and was getting the same output values but now when I say for(i=0; i<9; i++) it outputs as false every time. It is still not actually comparing the swipe value against the array values correct? It will only be true if swipe=9 as it's currently written? FWIW, I can see the value of swipe changing each time the program runs. Sorry, tried to go back and edit my last comment but it's not letting me change it now. – NewMC Mar 02 '16 at 20:22
0

In addition to @kaylum's answer...

Because you are calling rand() in a loop, you need to call srand() first before entering the loop,

srand(clock());//for example
while(1){
    LATD=0x00;
    int swipe=rand() % 20;
    ...   

If you do not, the random numbers you get will be the same sequence of values every time you execute.

Additionally, if i is not reinitialized before being used to compare, it is == 10. It needs to be reset before using as your array index...

Also, in your code, it appears you want to check the latest random number against the 10 accepted passwords. If that is correct, you must compare all 10 of them:

int main(void)
{
    srand(clock());//for example
    j = 0;
    while(1)
    {
        int swipe=rand() % 20;
        PORTD=0b00000000;
        for(i=0;i<10;i++)
        {
            j++;
            if(swipe == array[i]) 
            {
                PORTD=0b10000000;
                break;
            } 

        }
        //to show ratio of legal to illegal passcodes...
        printf("times through: %d  Value of PORTD %d\n", j, PORTD);
    }
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • ok, will do, thank you. – NewMC Mar 02 '16 at 20:26
  • This checks swipe against array[i] ten times but while swipe=18 it still comes out as false. Sorry all, I know there is something fairly simple I'm not connecting but just not experienced with this. – NewMC Mar 02 '16 at 20:39
  • @NewMC - That is true. I assume that because you specified this was a _Simulated code read from card swipe_, that you want to test against both legal and illegal passcode choices. You have an array of 10 _legal_ passcodes. If you have a _pseudo random_ generator that creates from 0 to 20, it is only to be expected that 1/2 the time the value will be illegal. Please explain (in your original post above) clearly what it is that you want. – ryyker Mar 02 '16 at 20:45
  • @ Ryyker - Do you want me to change the entire question? The code has changed due to the assistance that you good people have kindly offered. It is working as it is written, however; when any of the values of array[i] are equal to the current value of swipe I need to exit under the if statement (exit as PORTD=0b10000000). Currently, if swipe=18 the iteration of the if statement where array[i]=18 is true, but then it evaluates array[i]=19 and passes as false. So in this case, even though I have a swiped code that matches a legal passcode it has not sent the signal to unlock the latch. – NewMC Mar 02 '16 at 21:09
  • I don't think you need to change the whole question. Just clarify a few points. It has not been clear on what your exit criteria is. Or even is the code snippet you provided was just a test to see if your rand() generator was working to throw legal and illegal pass codes at the ports. This in part was why I edited my example code to loop in the while (i.e. get a new simulated pass code), then test that new pass code against the array. Each time, exiting the loop with whether it passed or failed. In any case, I believe all of the answers provided have given some help. – ryyker Mar 02 '16 at 21:14
  • yes, I agree, all of the provided answers have helped me to make the code more effective, thank you. Now I just need it to exit the for loop while swipe is equal to any number in the array. – NewMC Mar 02 '16 at 21:23
  • I must not have saw your break command originally or I'd have had fixed after your first post. Thanks for all the help! – NewMC Mar 02 '16 at 21:52
  • @NewMC - I may not have had the break in there. I changed the post once you explained what you were after. You are welcome – ryyker Mar 02 '16 at 22:00
0

You are trying to simulate random card-reading actions & get both Pass/Fail at different instances. With swipe values between 1 to 20 and passwords only in the range 10, 19, you'd like to see if some instances fail. Is that correct?

If so, considering your rand() function returns only integer, set a breakpoint and probe for value of swipe. It seems to always has same value. Make rand() function better for wider statistical distribution. There are many sources to generate random integers like Linear Congruential Method etc.

Also that comparison should be looped for every value of array.

seshu
  • 131
  • 2
  • @ Seshu - Yes, as of now more than 50% of the time it will fail the if statement and pass the else, but what I need it to do is pass the if statement as soon as it becomes true. – NewMC Mar 02 '16 at 21:25