Skip to main content
inet_pton
Source Link

Update: I would discard sscanf() because it would accept spaces before the numbers; better use inet_pton() as @vnp suggested.

Update: I would discard sscanf() because it would accept spaces before the numbers; better use inet_pton() as @vnp suggested.

added 18 characters in body
Source Link

<stdbool.h>

Unless you need compatibility with C89 for some reason, I would use bool for the return type of the function and true and false as the possible values.

It helps readability.


sscanf()

This one depends on your performance needs. A solution using sscanf() will be much easier to understand with a simple look and also shorter in code, but may also be much slower (a benchmark would be appropriate).


<stdint.h>

Same as with bool: segs seems at first glance to be some string, but after some time I realized it's just an array of 8-bit unsigned integers. You should use uint8_t for that.

In case of <stdint.h> I would say that if you don't have it, you should do the typedefs yourself (enclosed in some #if) anyway. Don't do that with bool, however, which is very dangerous.


Unneeded cast

unsigned char *p;
int i;

...
*p = (unsigned char)i;

This cast is not needed.

Usually casts are very dangerous: they can hide bugs that otherwise the compiler would catch easily. Don't ever cast, unless you know a very good reason to.


BUG! (No, I was wrong)

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

This line returns 0 at the first dot it finds. The function doesn't work!

This if that comes later is always false due to that:

// Segment changeover.
if (*str == '.') {
        /// Unreachable code!!!
}

<ctype.h>

There are some functions in <ctype.h> that you should use:

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

That code above can be simplified to this one (and the comment is now even more obvious and therefore removed ;-):

if (!isdigit((unsigned char)*str))
        return 0;

NOTES: The standards require that the argument c for these functions is either EOF or a value that is representable in the type unsigned char. If the argument c is of type char, it must be cast to unsigned char.

This is necessary because char may be the equivalent of signed char, in which case a byte where the top bit is set would be sign extended when converting to int, yielding a value that is outside the range of unsigned char.

See man isdigit.

If you're going to use these functions, I would create an unsigned char pointer to alias the char * parameter, so that you don't need to cast all the time.

<stdbool.h>

Unless you need compatibility with C89 for some reason, I would use bool for the return type of the function and true and false as the possible values.

It helps readability.


sscanf()

This one depends on your performance needs. A solution using sscanf() will be much easier to understand with a simple look and also shorter in code, but may also be much slower (a benchmark would be appropriate).


<stdint.h>

Same as with bool: segs seems at first glance to be some string, but after some time I realized it's just an array of 8-bit unsigned integers. You should use uint8_t for that.

In case of <stdint.h> I would say that if you don't have it, you should do the typedefs yourself (enclosed in some #if) anyway. Don't do that with bool, however, which is very dangerous.


Unneeded cast

unsigned char *p;
int i;

...
*p = (unsigned char)i;

This cast is not needed.

Usually casts are very dangerous: they can hide bugs that otherwise the compiler would catch easily. Don't ever cast, unless you know a very good reason to.


BUG!

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

This line returns 0 at the first dot it finds. The function doesn't work!

This if that comes later is always false due to that:

// Segment changeover.
if (*str == '.') {
        /// Unreachable code!!!
}

<ctype.h>

There are some functions in <ctype.h> that you should use:

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

That code above can be simplified to this one (and the comment is now even more obvious and therefore removed ;-):

if (!isdigit((unsigned char)*str))
        return 0;

NOTES: The standards require that the argument c for these functions is either EOF or a value that is representable in the type unsigned char. If the argument c is of type char, it must be cast to unsigned char.

This is necessary because char may be the equivalent of signed char, in which case a byte where the top bit is set would be sign extended when converting to int, yielding a value that is outside the range of unsigned char.

See man isdigit.

If you're going to use these functions, I would create an unsigned char pointer to alias the char * parameter, so that you don't need to cast all the time.

<stdbool.h>

Unless you need compatibility with C89 for some reason, I would use bool for the return type of the function and true and false as the possible values.

It helps readability.


sscanf()

This one depends on your performance needs. A solution using sscanf() will be much easier to understand with a simple look and also shorter in code, but may also be much slower (a benchmark would be appropriate).


<stdint.h>

Same as with bool: segs seems at first glance to be some string, but after some time I realized it's just an array of 8-bit unsigned integers. You should use uint8_t for that.

In case of <stdint.h> I would say that if you don't have it, you should do the typedefs yourself (enclosed in some #if) anyway. Don't do that with bool, however, which is very dangerous.


Unneeded cast

unsigned char *p;
int i;

...
*p = (unsigned char)i;

This cast is not needed.

Usually casts are very dangerous: they can hide bugs that otherwise the compiler would catch easily. Don't ever cast, unless you know a very good reason to.


BUG! (No, I was wrong)

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

This line returns 0 at the first dot it finds. The function doesn't work!

This if that comes later is always false due to that:

// Segment changeover.
if (*str == '.') {
        /// Unreachable code!!!
}

<ctype.h>

There are some functions in <ctype.h> that you should use:

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

That code above can be simplified to this one (and the comment is now even more obvious and therefore removed ;-):

if (!isdigit((unsigned char)*str))
        return 0;

NOTES: The standards require that the argument c for these functions is either EOF or a value that is representable in the type unsigned char. If the argument c is of type char, it must be cast to unsigned char.

This is necessary because char may be the equivalent of signed char, in which case a byte where the top bit is set would be sign extended when converting to int, yielding a value that is outside the range of unsigned char.

See man isdigit.

If you're going to use these functions, I would create an unsigned char pointer to alias the char * parameter, so that you don't need to cast all the time.

quote
Source Link

<stdbool.h>

Unless you need compatibility with C89 for some reason, I would use bool for the return type of the function and true and false as the possible values.

It helps readability.


sscanf()

This one depends on your performance needs. A solution using sscanf() will be much easier to understand with a simple look and also shorter in code, but may also be much slower (a benchmark would be appropriate).


<stdint.h>

Same as with bool: segs seems at first glance to be some string, but after some time I realized it's just an array of 8-bit unsigned integers. You should use uint8_t for that.

In case of <stdint.h> I would say that if you don't have it, you should do the typedefs yourself (enclosed in some #if) anyway. Don't do that with bool, however, which is very dangerous.


Unneeded cast

unsigned char *p;
int i;

...
*p = (unsigned char)i;

This cast is not needed.

Usually casts are very dangerous: they can hide bugs that otherwise the compiler would catch easily. Don't ever cast, unless you know a very good reason to.


BUG!

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

This line returns 0 at the first dot it finds. The function doesn't work!

This if that comes later is always false due to that:

// Segment changeover.
if (*str == '.') {
        /// Unreachable code!!!
}

<ctype.h>

There are some functions in <ctype.h> that you should use:

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

That code above can be simplified to this one (and the comment is now even more obvious and therefore removed ;-):

if (!isdigit((unsigned char)*str))
        return 0;

NoteNOTES: The standards require that the argument c for these functions is either EOF or a value that is representable in the type unsigned char. If the argument c is of type char, it must be cast to unsigned char.

This is necessary because char may be the equivalent of signed char, in which case a byte where the top bit is set would be sign extended when converting to int, yielding a value that is outside the range of unsigned char.

See man isdigit.

If you're going to use these functions, I would create an unsigned char pointer to alias the char * parameter, so that you don't need to cast all the time.

<stdbool.h>

Unless you need compatibility with C89 for some reason, I would use bool for the return type of the function and true and false as the possible values.

It helps readability.


sscanf()

This one depends on your performance needs. A solution using sscanf() will be much easier to understand with a simple look and also shorter in code, but may also be much slower (a benchmark would be appropriate).


<stdint.h>

Same as with bool: segs seems at first glance to be some string, but after some time I realized it's just an array of 8-bit unsigned integers. You should use uint8_t for that.

In case of <stdint.h> I would say that if you don't have it, you should do the typedefs yourself (enclosed in some #if) anyway. Don't do that with bool, however, which is very dangerous.


Unneeded cast

unsigned char *p;
int i;

...
*p = (unsigned char)i;

This cast is not needed.

Usually casts are very dangerous: they can hide bugs that otherwise the compiler would catch easily. Don't ever cast, unless you know a very good reason to.


BUG!

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

This line returns 0 at the first dot it finds. The function doesn't work!

This if that comes later is always false due to that:

// Segment changeover.
if (*str == '.') {
        /// Unreachable code!!!
}

<ctype.h>

There are some functions in <ctype.h> that you should use:

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

That code above can be simplified to this one (and the comment is now obvious and therefore removed ;-):

if (!isdigit((unsigned char)*str))
        return 0;

Note: The standards require that the argument c for these functions is either EOF or a value that is representable in the type unsigned char. If the argument c is of type char, it must be cast to unsigned char.

This is necessary because char may be the equivalent of signed char, in which case a byte where the top bit is set would be sign extended when converting to int, yielding a value that is outside the range of unsigned char.

See man isdigit.

If you're going to use these functions, I would create an unsigned char pointer to alias the char * parameter, so that you don't need to cast all the time.

<stdbool.h>

Unless you need compatibility with C89 for some reason, I would use bool for the return type of the function and true and false as the possible values.

It helps readability.


sscanf()

This one depends on your performance needs. A solution using sscanf() will be much easier to understand with a simple look and also shorter in code, but may also be much slower (a benchmark would be appropriate).


<stdint.h>

Same as with bool: segs seems at first glance to be some string, but after some time I realized it's just an array of 8-bit unsigned integers. You should use uint8_t for that.

In case of <stdint.h> I would say that if you don't have it, you should do the typedefs yourself (enclosed in some #if) anyway. Don't do that with bool, however, which is very dangerous.


Unneeded cast

unsigned char *p;
int i;

...
*p = (unsigned char)i;

This cast is not needed.

Usually casts are very dangerous: they can hide bugs that otherwise the compiler would catch easily. Don't ever cast, unless you know a very good reason to.


BUG!

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

This line returns 0 at the first dot it finds. The function doesn't work!

This if that comes later is always false due to that:

// Segment changeover.
if (*str == '.') {
        /// Unreachable code!!!
}

<ctype.h>

There are some functions in <ctype.h> that you should use:

// Check numeric.
if (*str < '0' || *str > '9')
        return 0;

That code above can be simplified to this one (and the comment is now even more obvious and therefore removed ;-):

if (!isdigit((unsigned char)*str))
        return 0;

NOTES: The standards require that the argument c for these functions is either EOF or a value that is representable in the type unsigned char. If the argument c is of type char, it must be cast to unsigned char.

This is necessary because char may be the equivalent of signed char, in which case a byte where the top bit is set would be sign extended when converting to int, yielding a value that is outside the range of unsigned char.

See man isdigit.

If you're going to use these functions, I would create an unsigned char pointer to alias the char * parameter, so that you don't need to cast all the time.

quote
Source Link
Loading
added 2 characters in body
Source Link
Loading
ctype.h
Source Link
Loading
added 197 characters in body
Source Link
Loading
added 174 characters in body; added 85 characters in body; added 55 characters in body; edited body
Source Link
Loading
cast; added 35 characters in body
Source Link
Loading
Source Link
Loading