Better Idea or easier way to get IP address

IDE 1.02, UNO R3, also have LCD and a 12 key keypad0-9 and 'E' and "C'
I am writing a routine to allow a user to enter an IP address on the UNO if there is not one already entered. I have only included the code for this section

just curious if anyone sees a way to make more compact , not written in yet is the capturing of the ip and storeing it to eeprom. i would like suggestions on the most feasable way to do and also a suggestion on a way to validate whether it is a valid ip address. I have thought about validateing as it is entered for example
ABC.ABC.ABC.ABC , when A is intered only allow 0 1 or 2 to be entered and if user press three force it back to a 2. then when B is entered , allow 0-9 if A is 0 or 1 but only allow 0-5 if A = 2.
the other way is to allow anything to be typed and then when 'E' on keypad is pressed do sometype of check. what are your thoughts.
here is code so far

void getipaddress()
{
  boolean goodIP = false;
  byte IPpos = 1 ;
  lcd.setCursor(7,0);
  lcd.print("Enter IP Address");
  lcd.setCursor(1,1);
  lcd.print("000.000.000.000");
  lcd.setCursor(1,1);
  lcd.blink();
  do
  {
    char key = keypad.getKey();

    if (key != NO_KEY){
      if (key == 'C')//backup
      {
        if (IPpos == 5 || IPpos == 9 || IPpos == 13)//skip over decimal
        {

          IPpos -= 2;
          lcd.setCursor(IPpos, 1);

        }
        else if (IPpos == 1) //dont pass to left of first digit of ip
        {
        }
        else 
        {
          IPpos -= 1;
          lcd.setCursor(IPpos, 1);
        }
      }
      else if(key == 'E')
      {
        //code to validate and save to eeprom
      }
      else
      {
        if (IPpos == 3 || IPpos == 7 || IPpos == 11)//skip over decimal
        {
          lcd.setCursor(IPpos, 1);
          lcd.print(key);
          lcd.setCursor(IPpos+2, 1);
          IPpos += 2;
        }
        else if (IPpos == 15) //dont move past last digit of ip
        {
          lcd.setCursor(IPpos, 1);
          lcd.print(key);
          lcd.setCursor(IPpos , 1);
        }
        else
        {
          lcd.setCursor(IPpos, 1);
          lcd.print(key);
          IPpos += 1;
        }

      }
    }
  } 
  while (goodIP == false);



  //delay(100000000);


}
  }
    
  }
  }
  } while (goodIP == false);

Is your tab key broken? If so, use the Tools + Auto Format menu item to properly indent your code. That mess is too hard to follow.

PaulS:

  }

}
  }
  } while (goodIP == false);



Is your tab key broken? If so, use the Tools + Auto Format menu item to properly indent your code. That mess is too hard to follow.

Fixed, didnt know that existed but CTRL + T is my new best fried

You aren't doing anything with key except printing it. When it comes time to save the IP address being displayed on the LCD, how are you going to get that data?

Consistent placement of the { is the next hurdle. The code is much easier to read now.

PaulS:
You aren't doing anything with key except printing it. When it comes time to save the IP address being displayed on the LCD, how are you going to get that data?

Consistent placement of the { is the next hurdle. The code is much easier to read now.

that was a suggestion i wanted what would be the most feasable way to capture the IP and verify

You need a char array. Every time you adjust the printing position on the LCD and print a character, store the character in the corresponding position of the array. Remember that array indexes, like LCD column positions, start at 0.

PaulS:
You need a char array. Every time you adjust the printing position on the LCD and print a character, store the character in the corresponding position of the array. Remember that array indexes, like LCD column positions, start at 0.

so i created the array and i am filling it as the keys are pressed ( in the code if 'E' is pressed it moves the cursor to the right unless it is in last position then it will just print the array on line one of lcd for testing.

I also am checking for valid ip as it is entered.

what i would really like to do is take each part of the ip address that is in array for example ip address 123.145.167.189 is 15 chars in array, when i store to eeprom i want to write as 4 bytes so how do i go about converting portions of the array to a byte

void getipaddress()
{
  char IPaddr[16]= {
    '0','0','0','.','0','0','0','.','0','0','0','.','0','0','0'    };

  boolean goodIP = false;
  byte IPpos = 1 ;
  lcd.setCursor(7,0);
  lcd.print("Enter IP Address");
  lcd.setCursor(1,1);
  lcd.print("000.000.000.000");
  lcd.setCursor(1,1);
  lcd.blink();
  do
  {
    char key = keypad.getKey();

    if (key != NO_KEY){
      if (key == 'C')//backup
      {
        if (IPpos == 5 || IPpos == 9 || IPpos == 13)//skip over decimal
        {
          IPpos -= 2;
          lcd.setCursor(IPpos, 1);
        }
        else if (IPpos == 1) //dont pass to left of first digit of ip
        {
        }
        else 
        {
          IPpos -= 1;
          lcd.setCursor(IPpos, 1);
        }
      }
      else if(key == 'E')
      {
        //code to validate and save to eeprom
        if (IPpos == 15)
        {
          lcd.setCursor(4, 0);

          lcd.print(IPaddr);
        }
        else if (IPpos == 3 || IPpos == 7 || IPpos == 11)
        {
          lcd.setCursor(IPpos+2, 1);
          IPpos += 2;
        }
        else
        {
          lcd.setCursor(IPpos+1, 1);

          IPpos += 1;
        }
      }
      else
      {
        if (IPpos == 1 || IPpos == 5 || IPpos == 9 || IPpos == 13)
        {
          if (key > '2')
          {
            key = '2';
          }
          lcd.setCursor(IPpos, 1);
          IPaddr[IPpos - 1] = key;
          lcd.print(key);
          IPpos += 1;
        }
        else if (IPpos == 2 || IPpos == 6 || IPpos == 10 || IPpos == 14)
        {
          if (IPaddr[IPpos - 2] == '2' && key > '5')
          {
            key = '5';
          }
          lcd.setCursor(IPpos, 1);
          IPaddr[IPpos - 1] = key;
          lcd.print(key);
          IPpos += 1;
        }
        else if (IPpos == 3 || IPpos == 7 || IPpos == 11 || IPpos == 15)//skip over decimal
        {
          if (IPaddr[IPpos - 3] == '2' && IPaddr[IPpos - 2] == '5' && key > '5')
          {
            key = '5';
          }
          else if (IPaddr[IPpos - 3] == '0' && IPaddr[IPpos - 2] == '0' && key == '0' && (IPpos == 3 || IPpos == 15))
          {
            key = '1';
          }
          lcd.setCursor(IPpos, 1);
          IPaddr[IPpos - 1] = key;
          lcd.print(key);
          if (IPpos == 15)
          {
            lcd.setCursor(IPpos , 1);
          }
          else
          {
            lcd.setCursor(IPpos+2, 1);
            IPpos += 2;
          }
        }

        else
        {
          //lcd.setCursor(IPpos, 1);
          //lcd.print(key);
          //IPpos += 1;
        }
      }
    }
  } 
  while (goodIP == false);



  //delay(100000000);


}
  char IPaddr[16]= {
    '0','0','0','.','0','0','0','.','0','0','0','.','0','0','0'    };

would involve a lot less typing as

   char IPaddr[16] = "";

The second one results in a NULL terminated array of chars. There is no telling what is in elements 1, 2, 3, etc., but it doesn't matter because there is a NULL in 0.

          IPaddr[IPpos - 1] = key;

needs to be

          IPaddr[IPpos - 1] = key;
          IPaddr[IPpos] = '\0';

to keep the string NULL terminated.

When the 'E' key is pressed, you need to use the strtok() and atoi() functions to get the tokens (the parts between the dots) and convert them to numbers.

There are already types defined to hold IP addresses in the common ethernet libraries. Have you checked whether there are also library functions to parse a dotted decimal string into an IPv4 address? I would be surprised if there wasn't.

If you can't find anexisting implementation and want to roll your own, the way I'd tackle this problem is to split the input string into four sequences of decimal digits, convert each sequence of digits to a number and verify the number is in the range 0 .. 255. I'd return the result using the existing IP address type, although I suppose you could use a 32-bit int instead.

PaulS:

  char IPaddr[16]= {

'0','0','0','.','0','0','0','.','0','0','0','.','0','0','0'    };



would involve a lot less typing as


char IPaddr[16] = "";




The second one results in a NULL terminated array of chars. There is no telling what is in elements 1, 2, 3, etc., but it doesn't matter because there is a NULL in 0.

the reason i did this way is so that if a user presses E to the end without actually pressing numbers there will be a default already there



IPaddr[IPpos - 1] = key;



needs to be


IPaddr[IPpos - 1] = key;
          IPaddr[IPpos] = '\0';



to keep the string NULL terminated.
the last 16th position has the null, if i try like this and you backspace with c and change the value the null moves and i need to keep null at the end

When the 'E' key is pressed, you need to use the strtok() and atoi() functions to get the tokens (the parts between the dots) and convert them to numbers.

i will try these functions in a few minutes