Tom
Tom

Reputation: 2661

How do loops and char arrays work in C ?

I have a program that runs exactly how I want it to be:

#define BUF_SIZE 15

void passwordCheck (int digit)
{
static char buf[BUF_SIZE] ;
  static int  i = 0;
  char pw[]="1234" ;
  int pw_size = sizeof(pw)-1 ;
  int ret ;

  if (digit == 13)
  {
    for(i=0;i<BUF_SIZE;i++){                     //why do I need this? 
    }
    ret = memcmp(buf, pw, 4) ;                      //compares the array with the pw
      if (ret == 0 && buf[pw_size] == 0) 
      {
      printf("Access granted\n") ;
      }
      else
      {
      printf("Access denied\n") ;
      }
  }

  else {
     if (i > ((int)sizeof(buf) - 2))          //sets all values to 0 ?  
     {
        i = 0;
        memset(buf, 0, sizeof(buf)) ;
     }
     buf[i] = digit ;                  //stores a value
     buf[i++] = digit ;                //stores a values at the next stage   
  }
}

It checks if the user puts in the right password, if so Access is granted if not access is denied. Here's a Demo

But I am having problems with understanding.

So static int i is used so that i doesn't become 0 everytime when passwordCheck is called?

So if the user doesn't press 13, passwordCheck stores all values in an array via these two lines

buf[i] = digit ; 
buf[i++] = digit ;

if the function is called the first time, this if statement sets all values in the array to 0:

 if (i > ((int)sizeof(buf) - 2))
     {
        i = 0;
        memset(buf, 0, sizeof(buf)) ;
     }

Then, when the user presses 13 the content of the array will be check and via memcmp and if it matches Access is granted, if not Access is denied.

But here, in particular, I am wondering why do I need this for loop:

 for(i=0;i<BUF_SIZE;i++){
        }

If I comment it out the programm only gives me access one time and then never again. So I am assuming what it does is it resets all values in the area to NULL, so the same thing as memset(buf, 0, sizeof(buf)) ; ? If that is the case, why, isn't it just a loop?

Thanks in advance

Upvotes: 2

Views: 68

Answers (3)

nnn
nnn

Reputation: 4230

As your for loop is empty, it's only side-action is (you can replace it with):

i = BUF_SIZE;

As a side note, it is highly possible that the compiler / optimizer is already producing that code in the output, and there will be no overhead from having the (unneeded) for.

This is only called when you send the password terminator 13. After that, at the next call (for another password), the function will take again the main else branch, and because i was previously set to BUF_SIZE, will execute this, resetting your counter:

    i = 0;
    memset(buf, 0, sizeof(buf)) ;

Your main if could be simplified, and will work the same:

  if (digit == 13)
  {
    ret = memcmp(buf, pw, pw_size) ;   //compares the array with the pw
      if (ret == 0 && i == pw_size) 
      {
      printf("Access granted\n") ;
      }
      else
      {
      printf("Access denied\n") ;
      }
    i = 0; // Reset for next password input
  }

  else {
     buf[i++] = digit ; //store the value on current position and after increment the pos
  }

Upvotes: 2

alvits
alvits

Reputation: 6768

The code is a word parser digesting one character at a time. It resets after a full word is parsed. The full word ends with a carriage return \r ascii(13).

The function itself is meaningless without the main code showing how the function is being called.

Let's digest each block in the code.

if (digit == 13)

This checks if it is the end of the password \r. In this block, it resets i to greater than the size of buf - 2. This was done using a for loop but it can simply set i = 15. This is necessary so the next re-try the code knows it's a fresh new password. You will notice that in this code it compares the first 4 bytes of buf with the first 4 bytes of pw and it ensures that buf is terminated with \0. If it didn't check the termination, then 12345 will pass.

The else condition handles the initialization of buf and the storage of the characters passed to it.

In this block you will notice that it checks if i is greater than sizeof (buf) -2. This is the condition they used to signify that buf needs to be reset to 0s. Hence the for loop in the previous block which could have been simplified by setting the value of i with an assignment expression i = 15.

The 2nd line that stores digit into buf does the same thing as the previous line does, and in addition it increments i. The previous line becomes unnecessary.

The use of static storage makes the value of i persist across each function call. Finally, this is not thread safe.

Upvotes: 1

Md Shibbir Hossen
Md Shibbir Hossen

Reputation: 338

Without this for loop you can not check the else statement until your buf full or size is 15. Because when the digit is 13 then you reset the buffer by checking the value of i in else statement which is 15 by using the for loop. It just wastes time . so you can write i=15//max size of buffer

Upvotes: 1

Related Questions