Incrementing hex address

T

Tester Tester

hello every body.
I am working in address incrementation(+1) using c language.User
inputs a value which is in hex address and incremented by 1.
Suppose my address is - abc5:5723:2109:ffff:76af:82ea:9256:ffff.
So my output becomes - abc5:5723:2109:ffff:76af:82ea:9257:0000

I already parse the entire string and put it in 8 different array but
unable to do when the the last 4 digit reaches FFFF..I could not write
the logic of that last portion.can any body help me to solve the
problem?

My code is -

#include "stdafx.h"
#include "conio.h"
#include "stdio.h"
#include "string.h"


int _tmain(int argc, _TCHAR* argv[])
{
char address[] = "abc5:5723:2109:ffff:76af:82ea:9256:ffff";
printf("Your IPv6 address is ");
puts(address);
char a[10], b[10], c[10], d[10], e[10], f[10], g[10], h[10];
if(sscanf(address, "%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:
%10[^:]:%10[^:]:",a,b,c,d,e,f,g,h)==8)
{
//puts(a);
//puts(b);
}
int m,n,o,p,q,r,s,t;
sscanf(a,"%x", &m);
sscanf(b,"%x", &n);
sscanf(c,"%x", &o);
sscanf(d,"%x", &p);
sscanf(e,"%x", &q);
sscanf(f,"%x", &r);
sscanf(g,"%x", &s);
sscanf(h,"%x", &t);

t++;


printf("The final output is %x:%x:%x:%x:%x:%x:%x:%x",m,n,o,p,q,r,s,t);


getch();
return 0;

}

Output -

You IPv6 address is abc5:5723:2109:ffff:76af:82ea:9256:ffff
The final output is abc5:5723:2109:ffff:76af:82ea:9256:10000

Waiting for your reply.

Ayanava
 
B

Ben Bacarisse

Tester Tester said:
I am working in address incrementation(+1) using c language.

That thew me! "address" has a meaning in C, and it is not what you mean
by "address". It all becomes clear later, it would have been better to
start with "I want to increment an IP v6 address".
User
inputs a value which is in hex address and incremented by 1.
Suppose my address is - abc5:5723:2109:ffff:76af:82ea:9256:ffff.
So my output becomes - abc5:5723:2109:ffff:76af:82ea:9257:0000

I already parse the entire string and put it in 8 different array but
unable to do when the the last 4 digit reaches FFFF..I could not write
the logic of that last portion.can any body help me to solve the
problem?

That's tricky. I can solve the problem but that (quite correctly) is not
what you ask. To help you to solve it is harder. I'll try.

First, you are only starting to grasp the problem. Once you manage to
deal with a final ffff you will then have to deal with an address that
ends ffff:ffff. It's possible that just thinking about this more
general problem is enough to get you going again, but if not I make some
more remarks below that might do the trick.
My code is -

#include "stdafx.h"
#include "conio.h"

There is no for these. Your program can be written in 100% standard
portable C.
#include "stdio.h"
#include "string.h"

It's much better to put standard headers in said:
int _tmain(int argc, _TCHAR* argv[])

There is no need for this either, and it may contribute to another
problem below. Standard "hosted" C programs start:

int main(void)

or

int main(int argc, char *argv[])

(there are lots of variations on this second one, but any equivalent
declaration will do.)
{
char address[] = "abc5:5723:2109:ffff:76af:82ea:9256:ffff";
printf("Your IPv6 address is ");
puts(address);
char a[10], b[10], c[10], d[10], e[10], f[10], g[10], h[10];
if(sscanf(address, "%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:
%10[^:]:%10[^:]:",a,b,c,d,e,f,g,h)==8)

A format in the form %n[..] requires an array large enough for n+1
characters because a terminating null byte will be added. All sorts of
problem will occur if there ever are 10 or more digits in one of the
parts of the address.
{
//puts(a);
//puts(b);
}
int m,n,o,p,q,r,s,t;

A technical matter: int may not be "big enough". I'd use long and,
specifically, unsigned long. Even if you don't use int, you should use
unsigned int since both your scanf and printf formats require unsigned
int arguments (well, scanf requires are pointer of course, but you know
what I mean, I hope).
sscanf(a,"%x", &m);
sscanf(b,"%x", &n);
sscanf(c,"%x", &o);
sscanf(d,"%x", &p);
sscanf(e,"%x", &q);
sscanf(f,"%x", &r);
sscanf(g,"%x", &s);
sscanf(h,"%x", &t);

When you find yourself doing something many times, you should consider
writing a function to do it. Rather than scanning 10 strings and then
scanning those, I'd have function to turn a portion of the input
string into a number. Learning to spot when such functions are a good
idea is a crucial skill you will need to develop.

Secondly, when you find yourself writing a collection of variables like
this you should consider making them an array. In this case it will be
a key part of making the program clear and simple.

To return to initial (not quite complete) program, ask yourself
(a) when can the program simply do t++?
(b) when must it do something else?
(c) what must it do in that case?
(d) what part of C lets a program do one thing in some cases and another
in others?

I think if you can answer these, you'll have an answer to what you
asked. You'll need to extend it though to solve the actual problem.
printf("The final output is %x:%x:%x:%x:%x:%x:%x:%x",m,n,o,p,q,r,s,t);


getch();

The only explanation I've seen for this odd line is that is prevents a
window from disappearing when the program terminates. Feel free to
continue to use it, but you can, I think, solve the problem in other
ways that don't require any redundant input form the user.
return 0;

}

<snip>
 
M

Markus Wichmann

hello every body.
I am working in address incrementation(+1) using c language.User
inputs a value which is in hex address and incremented by 1.
Suppose my address is - abc5:5723:2109:ffff:76af:82ea:9256:ffff.
So my output becomes - abc5:5723:2109:ffff:76af:82ea:9257:0000

I already parse the entire string and put it in 8 different array but
unable to do when the the last 4 digit reaches FFFF..I could not write
the logic of that last portion.can any body help me to solve the
problem?

My code is -

#include "stdafx.h"
#include "conio.h"
#include "stdio.h"
#include "string.h"


int _tmain(int argc, _TCHAR* argv[])
{
char address[] = "abc5:5723:2109:ffff:76af:82ea:9256:ffff";
printf("Your IPv6 address is ");
puts(address);
char a[10], b[10], c[10], d[10], e[10], f[10], g[10], h[10];
if(sscanf(address, "%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:%10[^:]:
%10[^:]:%10[^:]:",a,b,c,d,e,f,g,h)==8)
{
//puts(a);
//puts(b);
}
int m,n,o,p,q,r,s,t;
sscanf(a,"%x", &m);
sscanf(b,"%x", &n);
sscanf(c,"%x", &o);
sscanf(d,"%x", &p);
sscanf(e,"%x", &q);
sscanf(f,"%x", &r);
sscanf(g,"%x", &s);
sscanf(h,"%x", &t);

t++;


printf("The final output is %x:%x:%x:%x:%x:%x:%x:%x",m,n,o,p,q,r,s,t);


getch();
return 0;

}

Output -

You IPv6 address is abc5:5723:2109:ffff:76af:82ea:9256:ffff
The final output is abc5:5723:2109:ffff:76af:82ea:9256:10000

Waiting for your reply.

Ayanava

Apart from your code having horrible style, I think if you actually want
to have a carry, you have to implement it. One way to do so:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char* argv[])
{
unsigned int addr[8];
char *argument = "abc5:5723:2109:ffff:76af:82ea:9256:ffff";

if (sscanf(argument, "%x:%x:%x:%x:%x:%x:%x:%x",
addr + 0,
addr + 1,
addr + 2,
addr + 3,
addr + 4,
addr + 5,
addr + 6,
addr + 7) < 8) {
fputs("argument is of wrong format\n", stderr);
return 1;
}

unsigned int carry = 1, i = 8;
while (carry && i)
{
addr[i-1] += carry;
if (addr[i-1] > 0xffff || !addr[i-1])
{
carry = 1;
addr[i-1] &= 0xffff;
} else carry = 0;
i--;
}
printf("Original address:\n%s\n"
"New address:\n%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
argument,
addr[0],
addr[1],
addr[2],
addr[3],
addr[4],
addr[5],
addr[6],
addr[7]);
if (carry) puts("also, an overflow occured");
return 0;
}
 
K

Keith Thompson

Ben Bacarisse said:
There is no for these. Your program can be written in 100% standard
portable C.

I think you mean there is no *need* for these.

Incidentally, since conio.h is a system header, it's best to use

#include <conio.h>

[big snip]
The only explanation I've seen for this odd line is that is prevents a
window from disappearing when the program terminates. Feel free to
continue to use it, but you can, I think, solve the problem in other
ways that don't require any redundant input form the user.

Note that if you choose to keep the getch() call, you *do* need to
include conio.h, since that's the (Windows-specific) header that
declare the getch() function.
 
T

Tester Tester

You are not taking into account the possible use of the double colon
in an IPv6 address to indicate a block of zeroes.  Also, leading zeroes
don't have to be written for any 4-hex-digit group.  For example:
        fe02::ffff
increments to:
        fe02::1:0

"Be liberal in what you accept as input and strict in what you generate
as output."  It's OK if you decide not to generate IPv6 addresses with
the double colon notation, or with or without leading zeroes in
4-digit groups, but your users will expect to be able to enter it
that way.

For those of you who claim that IPv6 addresses are off-topic, well,
this is an issue of input validation by a C program, which I think
is relevant.


8 *different arrays*?  I suggest putting it into a single array of
(presumably, 8) 16-bit integers.  An appropriate type for that array
might be unsigned short or uint16_t.  Then increment the last array
element, propagating carries to earlier elements if needed.


Do you know how to add 1 to a number using pencil and paper?  The
logic works much the same (although you may be doing it in base 16
or base 65536), except that carries out of a 4-digit group are
handled a bit differently from carries within a 4-digit group.

A lot of multiprecision math is better understood by going back to
the old grade-school, paper-and-pencil methods of calculating, with
a slight redefinition of what's a "digit".  The grade-school method
may not be the most efficient, but it works.

Beware of scanf().  It doesn't provide much opportunity to check
the validity of user input.  For example, this input:
   2022:supercalifragilisticexpialidoxious::7q9:43:1
or even:
   abc5:5723:2109:ffffffffffffffffffffffffffffffffffffffff:76af:82ea:9256:ffff
might seriously confuse your program.

Thank you very much for your help.
 
J

Jorgen Grahn

....

"Be liberal in what you accept as input and strict in what you generate
as output." It's OK if you decide not to generate IPv6 addresses with
the double colon notation, or with or without leading zeroes in
4-digit groups

It's OK, but you need to be aware that you're breaking RFC 5952,
"A Recommendation for IPv6 Address Text Representation".

/Jorgen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top