elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  decimal a octal
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: decimal a octal  (Leído 3,675 veces)
Ander123

Desconectado Desconectado

Mensajes: 101


Ver Perfil
decimal a octal
« en: 27 Agosto 2012, 14:48 pm »

Hola, como hago para decir que quiero que un numero x sea descompuesto entre potencias de ocho con un "do...while"


En línea

ecfisa

Desconectado Desconectado

Mensajes: 114


Ver Perfil
Re: decimal a octal
« Respuesta #1 en: 28 Agosto 2012, 16:29 pm »

Hola Ander123.

No entiendo muy bién lo que buscas pero a ver si esto te sirve...

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. /* Convierte numero en base 10 a base 2,3,..., N (probe hasta base 36) */
  5. char *b10base_n(int num, unsigned char base) {
  6.  char tmp[255], res[255];
  7.  int mod, i, h=0;
  8.  
  9.  memset(tmp,'0',255);
  10.  memset(res,'0',255);
  11.  do {
  12.    mod = num % base;
  13.    num = num / base;
  14.    if (mod < 10)
  15.      tmp[h] = (char)mod + '0';
  16.    else
  17.      tmp[h] = (char)mod + '7';
  18.    h++;
  19.  } while (num > 0);
  20.  tmp[h] = '\0';
  21.  
  22.  for(i=0; i < h; i++) res[i] = tmp[h-i-1];
  23.  res[i] = '\0';
  24.  
  25.  return res;
  26. }
  27.  
  28. /* Ejemplo de uso */
  29. int main(int argc, char* argv[])
  30. {
  31.  int numero, base;
  32.  printf("Numero en base 10: ");
  33.  scanf("%d",&numero);
  34.  printf("\nBase a la que convierte: ");
  35.  scanf("%d",&base);
  36.  printf("\n%d en base %d es: %s",numero,base, b10base_n(numero,base));
  37.  
  38.  while(getchar()!='\n');
  39.  getchar();
  40.  return 0;
  41. }
  42.  

Saludos.


« Última modificación: 28 Agosto 2012, 16:32 pm por ecfisa » En línea

fabianjsm

Desconectado Desconectado

Mensajes: 26


Ver Perfil WWW
Re: decimal a octal
« Respuesta #2 en: 30 Agosto 2012, 06:08 am »

Hola ecfisa. Estas retornando el puntero a una variable automatica! Si lo solucionas declarándola como estática sigues en problemas, porque este código fallaría:

Código
  1. char *a = b10base_n(100,10);
  2. char *b = b10base_n(20,10);
  3. printf("%s != %s\n", a, b);

A no ser que tomes siempre la precaución de copiar el dato después de cada llamada a la función b10base_n

Código
  1. char a[32], b[32];
  2. strcpy(a, b10base_n(100,10));
  3. strcpy(b, b10base_n(20,10));
  4. printf("%s != %s\n", a, b);

Una de las soluciones podría ser reservar memoria con malloc o retornar haciendo return strdup(res), recordando liberar la memoria después. Por eso las funciones de este tipo en C trabajan con un puntero al buffer. En C++ retornas un std::string y problema resuelto.
El código no falla, esta haciendo lo que tú has programado, pero el resultado no es el deseado (error lógico)
« Última modificación: 30 Agosto 2012, 06:12 am por fabianjsm » En línea

ecfisa

Desconectado Desconectado

Mensajes: 114


Ver Perfil
Re: decimal a octal
« Respuesta #3 en: 30 Agosto 2012, 11:55 am »

Hola fabianjsm.

Entiendo lo que me comentas y llevas toda la razón, ¿ De este modo te parece mas correcto ?

Código
  1. char *base10basen(int num, unsigned char base) {
  2.  char t1[255],t2[255];
  3.  int mod, i, h=0;
  4.  do {
  5.    mod = num % base;
  6.    num = num / base;
  7.    if (mod < 10)
  8.      t1[h] = (char)mod + '0';
  9.    else
  10.      t1[h] = (char)mod + '7';
  11.    h++;
  12.  } while (num > 0);
  13.  t1[h] = '\0';
  14.  
  15.  for(i=0; i < h; i++) t2[i] = t1[h-i-1];
  16.  t1[i] = '\0';
  17.  return strdup(t1);
  18. }
  19.  
Pero no veo otra forma que liberar la memoria fuera de la función...

Y si, usando string es muchísimo más simple.

Saludos.


En línea

leosansan


Desconectado Desconectado

Mensajes: 1.314


Ver Perfil
Re: decimal a octal
« Respuesta #4 en: 30 Agosto 2012, 15:19 pm »

Ander debes currrate el código antes, lo que tienes de código es "muy flojo", con muchos errores simples. Para que no te quedes en blanco te dejo el siguiente código. Por cierto, varian BASE a 2 puedes pasar a binario u otra base:
Código:
#include<stdio.h>
#define BASE      8
 int   main()
{
    register int i=0,j,k =1;
    long long int n, N;
    printf ("Entre numero entero en base 10:\t"); scanf ("%lld",&N);
    n=N;
    while (n/BASE>=1)
        {
            n/=BASE; k++;
        }
    /*printf ("\nk =%d ",k);*/
    n=N;
    long long int digito[k];
    while (n/BASE>=1)
        {
            digito[i] = n%BASE;
            n/=BASE; i++;
        }
    digito[i] = n%BASE;
    printf ("\n%lld (en base %d) es igual a :  ",N,BASE);
    for( j=i ; j>=0 ;j-- ) printf ("%lld",digito[j]);
    puts  ("\n");
    return 0;
}
Puedes comprobar la conversion en la siguiente página:
http://es.ncalculators.com/digital-computation/decimal-octal-converter.htm
En línea

fabianjsm

Desconectado Desconectado

Mensajes: 26


Ver Perfil WWW
Re: decimal a octal
« Respuesta #5 en: 31 Agosto 2012, 06:51 am »

La memoria debe ser liberada con free (incluso en C++, a no ser que modifiques tu función para que reserve memoria con new), strdup hace esto (copy paste de la libreria):

Código
  1. char *strdup (const char *s)
  2. {
  3.    char *d = malloc (strlen (s) + 1);
  4.    if (d != NULL)
  5.        strcpy (d,s);
  6.    return d;
  7. }

Una alternativa elegante (en la librería GNU C) es strdupa (y strndupa), similar a strdup pero que asigna memoria en la pila, esto hace que no sea necesario liberar la memoria, ya que esta es liberado automáticamente al salir de la función que invocó a strdupa. Funciona sin problemas en C++, y por contraparte debes recordar no liberar la memoria ;-)

Ander debes currrate el código antes

Muy cierto, haber si nos muestras algún adelanto Ander123!
« Última modificación: 31 Agosto 2012, 06:55 am por fabianjsm » En línea

ecfisa

Desconectado Desconectado

Mensajes: 114


Ver Perfil
Re: decimal a octal
« Respuesta #6 en: 31 Agosto 2012, 14:16 pm »

Hola fabianjsm.
Citar
La memoria debe ser liberada con free (incluso en C++)
Obviamente, eso está fuera de toda duda. Pero me refería a que no encontre modo de liberar la memoria  no siendo fuera de la función.

Por ejemplo:
Código
  1. ...
  2. char *base10basen(int num, unsigned char base) {
  3.  char t1[255],t2[255];
  4.  int mod, i, h=0;
  5.  do {
  6.    mod = num % base;
  7.    num = num / base;
  8.    if (mod < 10)
  9.      t1[h] = (char)mod + '0';
  10.    else
  11.      t1[h] = (char)mod + '7';
  12.    h++;
  13.  } while (num > 0);
  14.  t1[h] = '\0';
  15.  
  16.  for(i=0; i < h; i++) t2[i] = t1[h-i-1];
  17.  t1[i] = '\0';
  18.  return strdup(t1);
  19. }
  20.  
  21. int main() {
  22. char *a[10];
  23.  int i;
  24.  
  25.  for(i=0; i < 10; i++) a[i] = base10basen(i*10,16);
  26.  for(i=0; i < 10; i++) printf("%s\n",a[i]);
  27.  for(i=0; i < 10; i++) free(a[i]);
  28.  ...
  29. }
  30.  
La memoria se reserva en el heap ya que si se haciera en el stack el valor se perdería al retornar de la función.

Es decir que no encuentro forma de encapsular la reserva/liberación de la memoria dentro de la función, ya que si se libera antes de return es claro que devuelve cualquier cosa y despues de él no tiene efecto...


Saludos.


« Última modificación: 31 Agosto 2012, 14:33 pm por ecfisa » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines