Thread: If someone could explain this.

  1. #1
    Registered User
    Join Date
    Oct 2018
    Posts
    21

    If someone could explain this.

    Hello and thank you for taking your time to expalin me some things

    So I didn't write this program, I found it online so I would like to know some things a bit more.

    This is a program that tests if you have given an IPv4 (ip address) or not...

    Code:
    #include <stdio.h>
    
    #define QUAD  4     /* if you need a constant define one (or more) */
    #define MAXC 17     /* don't skimp on buffer size */
    
    int main (void)
    {
        char buf[MAXC] = "",    /* buf to hold IP read by fgets */
        nl = 0;                 /* charater to validate newline following IP */
        int ip[QUAD] = {0};     /* array to store each quad for testing */
    
        printf ("Enter IP address (x.x.x.x): ");
        fgets (buf, MAXC, stdin);        /* read IP into buf */
            if (sscanf (buf, "%d.%d.%d.%d%c",   /* parse with sscanf */
                        &ip[0], &ip[1], &ip[2], &ip[3], &nl) != 5) {
                fprintf (stderr, "error: invalid IPv4 format.\n");
                return 1;
            }
         for (int i = 0; i < QUAD; i++)      /* loop over each quad */
            if (ip[i] < 0 || 255 < ip[i]) { /* validate 0-255 */
               fprintf (stderr, "error: invalid quad '%d'.\n", ip[i]);
               return 1;
               }
        
        if (nl != '\n') {   /* validate following char is '\n' */
            fprintf (stderr, "error: additional characters following IP.\n");
            return 1;
        }
    
    
        printf ("valid IP: %s", buf);   /* all tests passed - good address */
    
        return 0;
    }

    So here
    Code:
     if (sscanf (buf, "%d.%d.%d.%d%c",   /* parse with sscanf */
                        &ip[0], &ip[1], &ip[2], &ip[3], &nl) != 5){
                fprintf (stderr, "error: invalid IPv4 format.\n");
                return 1;
            }
    I have never used sscanf before btw.
    So buf is where the program is reading from, then this here "%d.%d.%d.%d%c" now these dots there.
    Does this mean, that I need to put these dots in stdin because sscanf just sees these 3 dots between numbers so they need to be in stdin as well.

    And this %c, so this %c char is put into &nl, and later on in the code its said
    Code:
    if (nl != '\n') {   /* validate following char is '\n' */
            fprintf (stderr, "error: additional characters following IP.\n");
            return 1;
    , now does stdin actually save when I press enter as an \n character?

    And also this !=5, now I understand the if(...) and what !=5 means.

    (sscanf (buf, "%d.%d.%d.%d%c", &ip[0], &ip[1], &ip[2], &ip[3], &nl) != 5)

    But what is it looking for here the !=5, what should be equal to 5.
    Is the !=5 so that the 5 &, every single & gets a value?
    When i write (a!=4) ik that if a is 4 the statement is false.

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I have never used sscanf before btw.
    Have you at least found and read some documentation for sscanf()?

    So buf is where the program is reading from,
    Yes buf is the string that sscanf() is reading from.

    now these dots there.
    Does this mean, that I need to put these dots in
    Yes, if sscanf() expects the string to have those dots.

    , now does stdin actually save when I press enter as an \n character?
    No, stdin doesn't "save" anything it is a stream that is being read by some function, in this case that function is fgets().

    Now did you find and read any documentation for the fgets() funciton?

    And also this !=5, now I understand the if(...) and what !=5 means.

    (sscanf (buf, "%d.%d.%d.%d%c", &ip[0], &ip[1], &ip[2], &ip[3], &nl) != 5)
    Do you understand that sscanf() returns a value? Perhaps you should read the documentation you found for sscanf()?

  3. #3
    Registered User
    Join Date
    Oct 2018
    Posts
    21
    Thanks, so yea for sscanf() I found this "On success, the function returns the number of variables filled". So that explains the !=5.

    As for fgets(), it reads a line from the specified stream (stdin) and stores it into the string pointed to by buf.
    Now since this program works, and correct me if I´m wrong, fgets reads a line from the stream stdin, and in that line at the end is \n if I have pressed ENTER when I run the program.
    And then it stores all of it into the string pointed by buf.
    With sscanf I saved the character after the number(%d) from the string char buf[MAXC] into nl.

    And then i use this code to see if the user has pressed enter or something else after the number (%d) right?
    Code:
     if (nl != '\n') {   /* validate following char is '\n' */       
     fprintf (stderr, "error: additional characters following IP.\n");
            return 1;
        }
    Last edited by JohnnyC; 11-03-2018 at 03:45 PM.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by JohnnyC View Post
    Thanks, so yea for sscanf() I found this "On success, the function returns the number of variables filled". So that explains the !=5.

    As for fgets(), it reads a line from the specified stream (stdin) and stores it into the string pointed to by buf.
    Now since this program works, and correct me if I´m wrong, fgets reads a line from the stream stdin, and in that line at the end is \n if I have pressed ENTER when I run the program.
    And then it stores all of it into the string pointed by buf.
    With sscanf I saved the last character from the string char buf[MAXC] into nl.

    And then i use this code to see if the user has pressed enter or something else after the number (%d) right?
    Code:
     if (nl != '\n') {   /* validate following char is '\n' */        fprintf (stderr, "error: additional characters following IP.\n");
            return 1;
        }
    Right, the formats for sscanf are the same as scanf; so if there's any matching failure (non-space characters other than dots etc) you'll fall short of the five, and assuming we get that far the character after the last number gets stored in nl. (I say non-space since %d will skip over spaces before a number; %c won't, which is why it can grab the new-line character.)

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    fgets reads a line from the stream stdin, and in that line at the end is \n
    Yes but be careful to insure that the "buffer" is large enough to hold the desired string including the new line character and the end of string character. If the buffer is not large enough then the new line character will not be contained in the string. The lack of a new line character tells you that there is more information in the input buffer that still needs to be examined.

    By the way this program should handle this issue, but it is something you need to be aware of when using fgets() for other purposes.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. no one is able to explain!
    By c_lady in forum C Programming
    Replies: 3
    Last Post: 05-12-2010, 09:47 AM
  2. please explain
    By moment in forum C++ Programming
    Replies: 1
    Last Post: 05-19-2009, 08:20 AM
  3. Could someone explain this?
    By cboard_member in forum C++ Programming
    Replies: 4
    Last Post: 02-14-2006, 08:44 AM
  4. Replies: 1
    Last Post: 03-04-2003, 11:46 AM
  5. can someone explain how this is possible
    By Shadow12345 in forum Game Programming
    Replies: 9
    Last Post: 12-29-2002, 09:31 AM

Tags for this Thread