Concat 4 enteros en un entero

Hola, estoy tratando de concatinar 4 enteros un entero. Usé la función concatinar encontrada aquí:

https://stackoverflow.com/a/12700533/2016977

Mi código:

unsigned concatenate(unsigned x, unsigned y) { unsigned pow = 10; while(y >= pow) pow *= 10; return x * pow + y; } void stringtoint(){ struct router *ptr; ptr=start; while(ptr!=NULL){ int a; int b; int c; int d; sscanf(ptr->ip, "%d.%d.%d.%d", &a, &b, &c, &d); int num1 = concatenate(a,b); int num2 = concatenate(c,d); int num3 = concatenate(num1,num2); printf("%d\n",num3); ptr=ptr->next; }; } 

El problema:

Estoy tratando con números de direcciones IP, por ejemplo, 198.32.141.140 estoy dividiendo en 4 enteros y los concatené para formar 19832141140 , sin embargo, mi función de concatenar está haciendo 198.32.141.140 matemáticos en el número más grande como 198.32.141.140 (se convierte) -> -1642695340 pero está concatenando la IP que son números pequeños, por ejemplo, 164.78.104.1 convierte en 164781041 (lo que es correcto)

¿Cómo debo resolver el problema, básicamente estoy tratando de hacer una cadena de IP, por ejemplo, 198.32.141.140 en un número entero 19832141140

Su enfoque propuesto es probablemente un error muy grande. ¿Cómo se distingue 127.0.1.1 de 127.0.0.11 ?

Es mucho mejor tratar las direcciones IP exactamente como son. A saber, abcd representa

 a * 256^3 + b * 256^2 + c * 256^1 + d * 256^0 

y hecho de esta manera no es posible que te encuentres con el problema que acabo de describir. Además, la implementación es trivial:

 unsigned int number; number = (a << 24) + (b << 16) + (c << 8) + d 

Puede leer una línea y luego usar inet_aton() . De lo contrario, puede hacer lo que Jason dice, pero debería verificar que el valor de cada número entero esté dentro de 0 … 255 (esos 4 x 8 bits representan el número entero de 32 bits que contiene una dirección IPv4). inet_aton() notación hexadecimal, dec y octal de direcciones IPv4.

 /** ** You DO NOT want to do this usually... **/ #include  uint_fast64_t concatIPv4Addr(uint_fast16_t parts[]) { uint_fast64_t n = 0; for (int i = 0; i < 3; ++i) { n += parts[i]; n *= 1000; } return (n += parts[3]); } 

Utilicé los tipos enteros "rápidos" para propósitos de velocidad, pero si tiene un requisito de almacenamiento, use los tipos "menos" correspondientes en su lugar. Por supuesto, esto supone que tienes un comstackdor C99 o un comstackdor C89 con extensiones. De lo contrario, se queda atascado con los tipos primitivos en los que una char incluso podría ser de 32 bits según el estándar C. Como no conozco su entorno objective, no hice suposiciones. Siéntase libre de cambiar a los tipos primitivos apropiados como mejor le parezca.

Utilicé un valor de 16 bits (mínimo) porque un número de 8 bits solo puede representar 0-255, lo que significa que si 358 se ingresó accidentalmente, se interpretaría como 102, que aún es válido. Si tiene un tipo capaz de almacenar más de 8 bits y menos de 16 bits, obviamente puede usar eso, pero el tipo debe poder almacenar más de 8 bits.

Aparte de eso, necesitará al menos un tipo de 38 bits:

 4294967295 (32-bit unsigned max) 255255255255 (255.255.255.255 converted to the integer you want) 274877906944 (38-bit unsigned max) 

La función anterior convertirá 127.0.1.1 y 127.0.0.11 a 127000001001 y 127000000011 respectivamente:

 127.0.1.1 -> 127.000.001.001 -> 127000001001 127.0.0.11 -> 127.000.000.011 -> 127000000011 

¿Por qué tantos ceros? Porque de lo contrario no se puede notar la diferencia entre ellos! Como han dicho otros, podría confundir 127.0.1.1 y 127.0.0.11. Usando la función anterior o algo más apropiado que realmente convierte una dirección IPv4 a su representación decimal real, no tendrá ese problema.

Por último, no hice ninguna validación en la dirección IPv4 pasada a la función. Supongo que ya se asegura de que la dirección sea válida antes de llamar a cualquier función que guarde o use la dirección IPv4. Por cierto, si quisiera hacer lo mismo con IPv6, no puede hacerlo tan fácilmente porque eso requeriría una cadena o conversión a decimal de cada una de las 8 partes, cada una de las cuales tiene un máximo de 16 bits, con 5 dígitos decimales. por parte, o 40 dígitos. Para almacenar eso, necesitaría un mínimo de 133 bits, en lugar de los 128 bits requeridos para la dirección IPv6, al igual que necesitaría 38 bits para almacenar una dirección IPv4 en lugar de los 32 bits requeridos.

Todavía no está tan mal, ¿verdad? ¿Qué tal un IPv8 teórico donde hay 16 partes, cada una de las cuales tiene un tamaño de 32 bits? La función equivalente a la anterior requeriría 580 bits, en lugar del requisito matemático adecuado: 512 bits. Si bien no es un problema hoy, simplemente estoy señalando el error al hacer algo con una dirección IPv4 representada por la concatenación de los valores decimales de cada parte. Se escala absolutamente terriblemente.