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

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


  Mostrar Mensajes
Páginas: [1] 2 3 4 5 6 7 8 9
1  Programación / Programación C/C++ / Re: Copiando cadenas - comportamientos extraños en: 23 Abril 2014, 05:54 am
Exacto, cuando la cadena es: 'hello, hi'

Este tendra 9 en longitud, y fgets se encargara de ponerle el '\0' al final, para cumplir con el maximo tamaño permitido, evitando caer en crash y si no me equivoco esto es lo que llaman buffer overflows.

Decia 'complejo' para poder obtener una cadena al menos de una forma segura, y de forma dinamica. Esto es debido por que estuve revisando una funcion que forma parte de un codigo que oculta todo estos detalles, expongo:

Código
  1. string GetString(void)
  2. {
  3.    // growable buffer for chars
  4.    string buffer = NULL;
  5.  
  6.    // capacity of buffer
  7.    unsigned int capacity = 0;
  8.  
  9.    // number of chars actually in buffer
  10.    unsigned int n = 0;
  11.  
  12.    // character read or EOF
  13.    int c;
  14.  
  15.    // iteratively get chars from standard input
  16.    while ((c = fgetc(stdin)) != '\n' && c != EOF)
  17.    {
  18.        // grow buffer if necessary
  19.        if (n + 1 > capacity)
  20.        {
  21.            // determine new capacity: start at 32 then double
  22.            if (capacity == 0)
  23.            {
  24.                capacity = 32;
  25.            }
  26.            else if (capacity <= (UINT_MAX / 2))
  27.            {
  28.                capacity *= 2;
  29.            }
  30.            else
  31.            {
  32.                free(buffer);
  33.                return NULL;
  34.            }
  35.  
  36.            // extend buffer's capacity
  37.            string temp = realloc(buffer, capacity * sizeof(char));
  38.            if (temp == NULL)
  39.            {
  40.                free(buffer);
  41.                return NULL;
  42.            }
  43.            buffer = temp;
  44.        }
  45.  
  46.        // append current character to buffer
  47.        buffer[n++] = c;
  48.    }
  49.  
  50.    // return NULL if user provided no input
  51.    if (n == 0 && c == EOF)
  52.    {
  53.        return NULL;
  54.    }
  55.  
  56.    // minimize buffer
  57.    string minimal = malloc((n + 1) * sizeof(char));
  58.    strncpy(minimal, buffer, n);
  59.    free(buffer);
  60.  
  61.    // terminate string
  62.    minimal[n] = '\0';
  63.  
  64.    // return string
  65.    return minimal;
  66. }

Anotar que el tipo de dato 'string', esta previamente definido en una libreria aparte como:
Código
  1. typedef char* string;

Aunque en este ultimo codigo no entiendo la linea:
Código
  1. string temp = realloc(buffer, capacity * sizeof(char));
Por que si buffer comenzo con NULL, al llegar a esta linea como que asignara NULL para temp, y esto a mi entender como que terminaria el programa  :-X

Saludos!
2  Programación / Programación C/C++ / Re: Copiando cadenas - comportamientos extraños en: 16 Abril 2014, 18:32 pm
Claro si defino una constante de un tamaño maximo y no sobrepase ese tamaño funcionara correctamente, de lo contrario esto resultaria en un crash, digamos asi:

Código
  1. char* saludo = malloc(10);
  2. /*...*/
  3. printf("Texto: ");
  4. fgets(saludo, 10, stdin);
  5. /*...*/

Al hacer pruebas obtenemos crash, si hago lo siguiente:
texto: hello, hi!

el texto "hello, hi!", tiene 10 en longitud faltando un '\0' para terminar la cadena, me provoca el crash. Es por eso que citaba "es bastante complejo leer cadenas" si se quiere hacer dinamicamente. y funciona correctamente si leo menores a 10 de longitud.

Saludos!
3  Programación / Programación C/C++ / Re: Copiando cadenas - comportamientos extraños en: 16 Abril 2014, 06:14 am
Gracias por sus respuestas.

Reconozco mi error grave de declarar un puntero sin inicializar, tenia un concepcion de querer hacerlo dinamico para la lectura de cadenas, veo que eso es altamente complejo.

Por que si declaro
Código
  1. char* saludo = malloc(100);
Es en si esquivalente ah:
Código
  1. char saludo[100]

Aunque desconozco si el declarar char, vayan al heap; caso que sucede con el malloc.

Ahora si quisiera usar fgets, tendria que saber de antemano cuanto caracteres voy a ingresar (lo digo por el segundo argumento "int length"), cosa que no se acomoda a mis intenciones.

Aceptar tambien que usar gets, era de muy pero muy mala practica acabo de observar que en los man-pages de la terminal gnu/linux, lo clasifican de obsoleto en el standard 2011.

Con respecto a esta linea de codigo:
Código
  1. malloc((strlen(saludo) + 1) * sizeof(char))
tengo un habito de calcular los arreglo y de ahi multiplicarlos por su tipo de dato, si este cambia a int, float y lo tengo ya ganado.
Pero estoy para aprender nuevos y buenos habitos, no se si estoy haciendo bien con el anterior malloc.

lo del strncpy, podria agregar una linea:
Código
  1. copysaludo[n] = '\0';

Pero muy elegante lo del sprintf, una linea y cumple el proposito.

Aprendiendo C, a paso de tortuga, jeje..

Saludos!
4  Programación / Programación C/C++ / Copiando cadenas - comportamientos extraños en: 15 Abril 2014, 07:32 am
Estaba revisando uno viejo libro que hace mucho tiempo imprimi, y me llamo la atencion, asi comienza parte del codigo:

Código
  1. char texto1[40], texto2[40]...
  2. ...
  3. gets(texto1)
  4. ...
  5. strncpy(texto3, texto2, 4);
  6. printf("Sus 4 primeras letras son %s\n", texto3);

Asi que como observer arreglos, quice hacerlo con punteros y ver su funcionamiento.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int main(void)
  6. {
  7.    char* saludo;
  8.    int n;
  9.  
  10.    printf("Texto: ");
  11.    gets(saludo);
  12.  
  13.    printf("Cuantas letras desea ver: ");
  14.    scanf("%d", &n);
  15.  
  16.    char* copySaludo = malloc((strlen(saludo) + 1) * sizeof(char));
  17.    strncpy(copySaludo, saludo, n);
  18.  
  19.    printf("Resultado con los %d primeras letras: %s\n", n, copySaludo);
  20.  
  21.    return 0;
  22. }

Lo curioso es que a veces tengo resultados muy fuera de si:
Citar
Texto: hello, world!
Cuantas letras desea ver: 6
Resultado con los 6 primeras letras: hello,>

Citar
Texto: hello, world!
Cuantas letras desea ver: 7
Resultado con los 7 primeras letras: hello,

Citar
Texto: hello, world!
Cuantas letras desea ver: 5
Resultado con los 5 primeras letras: hello♣>

Y a veces provoca un crash!

Es algo extraño, y confuso... creo que jugar con punteros es para super-heroes!
Saludos.
5  Programación / Bases de Datos / Consultas relacionadas sin JOIN en: 5 Julio 2013, 01:54 am
Que tal gente!

Una duda, se puede realizar consultas relacionadas sin joins de tal manera que muestre algun campo especifico de una llave foranea. Por ejemplo:

Código:
Carrera Estudiante
------- ----------
idCarrera PK idEstudiante PK
Titulo idCarrera FK
Nombres
Apellido

Código
  1. SELECT Estudiante.idCarrera AS [Carrera], Estudiante.Nombres, Estudiante.Apellido FROM Estudiante;
  2. SELECT Titulo FROM Carrera WHERE Carrera.idCarrera LIKE '%CS%';
  3.  
Código:
Carrera Nombres Apellidos
IS Jeff Parker
CS Mat Brown

Citar
Titulo
Ciencias de Computacion

Código
  1. SELECT Estudiante.idCarrera AS [Carrera], Estudiante.Nombres, Estudiante.Apellido FROM Estudiante WHERE Estudiante.idCarrera = (SELECT Carrera.Titulo FROM Carrera WHERE Carrera.idCarrera LIKE '%CS%');
  2.  
Código:
Carrera Nombres Apellidos

Aqui la informacion me aparece en blanco!

Lo que quiero lograr es algo parecido esto

Código:
Carrera Nombres Apellidos
Ciencias de computacion Mat Brown
6  Programación / Java / Re: Dos condiciones en estructura do-while en: 3 Junio 2013, 19:45 pm
Gracias por responder amigo, estado probando, lamentablemente seguia dando saltos inesperados,  yasi que estuve  razonando la logica que acabas de publicar. Recordando algo de logica proposicional, lo que mejor se ajustaba a este enunciado fue la logica proposicional de ' O inclusiva '.

Código
  1. int numero = entrada.nextInt();
  2.   while(numero <= 0 || numero > 100){
  3.      numero = entrada.nextInt();
  4. }

Funciona adecuadamente.  :laugh:
Pero mis jueces dicen que esto da lugar a un error de en tiempo de ejecucion (runtime error)   :-(

Cosa que sigo revisando.
Saludos
7  Programación / Java / Dos condiciones en estructura do-while en: 2 Junio 2013, 06:45 am
Esta pregunta es bastante novato, pero la verdad estoy llevando tiempo viendo por que no funciona.
Código
  1. do{
  2.   numero = ingresa.nextInt();
  3. }while(numero == 0 && numero > 100000)

La idea es ingresar un numero que este entre: 1<= n <100.
Y que sume naturalmente segun el numero ingresado.

Entrada:
2
5

Salida:
3
15

Pero si ingresas 0, es resultado es: 0.
Si ingresas 101, sale el resultado.
Cosa que debe  de seguir pidiendome leer numero.

Por ejemplo si hago asi:
Código
  1. do{
  2. do{
  3. numero = ingreso.nextInt();
  4. }while(numero == 0);
  5. }while(numero > 10000);

Hace correctamente, pero mi pregunta es por que no puedo hacerlo solo en un while?

Saludos.
8  Foros Generales / Foro Libre / Iron Man y Oracle Cloud en: 5 Mayo 2013, 19:19 pm
Hola a la gente despues de tiempos.
Estoy empezando con java y ando suscrito algunos magazines de Java.
Pero mi sorpresa fue encontrar un articulo en el Magazine de oracle de la edicion de mayo. Donde Hablan sobre Iron Man donde Stark Industries usa un servicio de Oracle, 'Oracle Cloud'.

Estuve leyendo y me pregunataba que pasaria si esto fuera real, sobre todo estado pendiente con los problemas de seguridad en Java y si tomarian controlando Stark Industries!  :o

Y que pasaria con Jarvis, el sistema de inteligencia artificial del exso-esqueleto de Iron Man, argumentando un disparate no croe use Java  :silbar:

Dejo el PDF donde se habla al respecto.

Engineered For Heroes
9  Programación / Programación C/C++ / Re: compresion - encriptacion con huffman - duda en: 10 Julio 2012, 13:28 pm
estoy cometiendo alguna falta a las reglas ....
o no esta habiendo actividad en el foro ... creo nadie me responde  :o
10  Programación / Programación C/C++ / compresion - encriptacion con huffman - duda en: 10 Julio 2012, 04:31 am
Hola a todos estoy analizando un codigo que consegui sobre este algoritmo de huffman, me intereso el tema de compresion, y despues de seguir  esta lectura pues observe que tambien era posible el cifrado de datos, asi que los puse en marcha y algunas pequeñas modificaciones que realize, aunque sigue siendo el mismo code.

Código
  1. #include <iostream>
  2. #include <cstdio>
  3.  
  4. using namespace std;
  5.  
  6. typedef struct _nodo{
  7.   char letra;
  8.   int frecuencia;
  9.  
  10.   _nodo *sig;
  11.   _nodo *cero;
  12.   _nodo *uno;
  13. } tipoNodo;
  14.  
  15.  
  16. typedef struct _tabla{
  17.   char letra;
  18.   unsigned long int bits;
  19.   char nbits;
  20.   _tabla *sig;
  21. } tipoTabla;
  22.  
  23. tipoTabla *Tabla;
  24.  
  25. void Cuenta(tipoNodo* &Lista, char c);
  26. void Ordenar(tipoNodo* &Lista);
  27. void InsertarOrden(tipoNodo* &Cabeza, tipoNodo *e);
  28. void BorrarArbol(tipoNodo *n);
  29. void CrearTabla(tipoNodo *n, int l, int v);
  30. void InsertarTabla(char c, int l, int v);
  31. tipoTabla *BuscaCaracter(tipoTabla *Tabla, char c);
  32.  
  33. int main(int argc, char *argv[]){
  34.   tipoNodo *Lista;
  35.   tipoNodo *Arbol;
  36.  
  37.   FILE *fe, *fs;
  38.   char c;
  39.   tipoNodo *p;
  40.   tipoTabla *t;
  41.   int nElementos;
  42.   long int Longitud = 0;
  43.  
  44.   unsigned long int dWORD;
  45.   int nBits;
  46.  
  47.   if(argc < 3)
  48.   {
  49.      cout<<"\n\tUsar:\n\t"<<argv[0]<<" <fichero_entrada> <fichero_salida>\n";
  50.      return 1;
  51.   }
  52.  
  53.   Lista = NULL;
  54.  
  55.   fe = fopen(argv[1], "r");
  56.   while((c = fgetc(fe)) != EOF){
  57.      Longitud++;
  58.      Cuenta(Lista, c);
  59.   }
  60.   fclose(fe);
  61.  
  62.   Ordenar(Lista);
  63.  
  64.   Arbol = Lista;
  65.   while(Arbol && Arbol->sig){
  66.      p = new(tipoNodo);
  67.      p->letra = 0;
  68.      p->uno = Arbol;
  69.      Arbol = Arbol->sig;
  70.      p->cero = Arbol;
  71.      Arbol = Arbol->sig;
  72.      p->frecuencia = p->uno->frecuencia + p->cero->frecuencia;
  73.      InsertarOrden(Arbol, p);
  74.   }
  75.  
  76.   Tabla = NULL;
  77.   CrearTabla(Arbol, 0, 0);
  78.  
  79.   fs = fopen(argv[2], "wb");
  80.  
  81.   fwrite(&Longitud, sizeof(long int), 1, fs);
  82.  
  83.   nElementos = 0;
  84.   t = Tabla;
  85.   while(t){
  86.      nElementos++;
  87.      t = t->sig;
  88.   }
  89.  
  90.   fwrite(&nElementos, sizeof(int), 1, fs);
  91.  
  92.   t = Tabla;
  93.   while(t)
  94.   {
  95.      fwrite(&t->letra, sizeof(char), 1, fs);
  96.      fwrite(&t->bits, sizeof(unsigned long int), 1, fs);
  97.      fwrite(&t->nbits, sizeof(char), 1, fs);
  98.      t = t->sig;
  99.   }
  100.  
  101.  
  102.   fe = fopen(argv[1], "r");
  103.   dWORD = 0;
  104.   nBits = 0;
  105.   while((c = fgetc(fe)) != EOF)
  106.   {
  107.  
  108.      t = BuscaCaracter(Tabla, c);
  109.  
  110.      while(nBits + t->nbits > 32){
  111.         c = dWORD >> (nBits-8);
  112.         fwrite(&c, sizeof(char), 1, fs);
  113.         nBits -= 8;
  114.      }
  115.      dWORD <<= t->nbits;
  116.      dWORD |= t->bits;
  117.      nBits += t->nbits;
  118.   }
  119.  
  120.   while(nBits>0){
  121.      if(nBits>=8) c = dWORD >> (nBits-8);
  122.      else c = dWORD << (8-nBits);
  123.      fwrite(&c, sizeof(char), 1, fs);
  124.      nBits -= 8;
  125.   }
  126.  
  127.   fclose(fe);
  128.   fclose(fs);
  129.  
  130.  
  131.   BorrarArbol(Arbol);
  132.  
  133.   while(Tabla){
  134.      t = Tabla;
  135.      Tabla = t->sig;
  136.      delete(t);
  137.   }
  138.  
  139.   return 0;
  140. }
  141.  
  142. void Cuenta(tipoNodo* &Lista, char c){
  143.   tipoNodo *p, *a, *q;
  144.  
  145.   if(!Lista){
  146.      Lista = new(tipoNodo);
  147.      Lista->letra = c;
  148.      Lista->frecuencia = 1;
  149.      Lista->sig = Lista->cero = Lista->uno = NULL;
  150.   }
  151.   else{
  152.      p = Lista;
  153.      a = NULL;
  154.      while(p && p->letra < c){
  155.         a = p;
  156.         p = p->sig;
  157.      }
  158.  
  159.      if(p && p->letra == c) p->frecuencia++;
  160.      else{
  161.         q = new(tipoNodo);
  162.         q->letra = c;
  163.         q->frecuencia = 1;
  164.         q->cero = q->uno = NULL;
  165.         q->sig = p;
  166.         if(a) a->sig = q;
  167.         else Lista = q;
  168.      }
  169.   }
  170. }
  171.  
  172. void Ordenar(tipoNodo* &Lista){
  173.   tipoNodo *Lista2, *a;
  174.  
  175.   if(!Lista) return;
  176.   Lista2 = Lista;
  177.   Lista = NULL;
  178.   while(Lista2){
  179.      a = Lista2;
  180.      Lista2 = a->sig;
  181.      InsertarOrden(Lista, a);
  182.   }
  183. }
  184.  
  185. void InsertarOrden(tipoNodo* &Cabeza, tipoNodo *e)
  186. {
  187.   tipoNodo *p, *a;
  188.  
  189.   if(!Cabeza){
  190.      Cabeza = e;
  191.      Cabeza->sig = NULL;
  192.   }
  193.   else{
  194.       p = Cabeza;
  195.       a = NULL;
  196.       while(p && p->frecuencia < e->frecuencia){
  197.          a = p;
  198.          p = p->sig;
  199.       }
  200.  
  201.       e->sig = p;
  202.       if(a) a->sig = e;
  203.       else Cabeza = e;
  204.    }
  205. }
  206.  
  207. void CrearTabla(tipoNodo *n, int l, int v){
  208.   if(n->uno)  CrearTabla(n->uno, l+1, (v<<1)|1);
  209.   if(n->cero) CrearTabla(n->cero, l+1, v<<1);
  210.   if(!n->uno && !n->cero) InsertarTabla(n->letra, l, v);
  211. }
  212.  
  213. void InsertarTabla(char c, int l, int v){
  214.   tipoTabla *t, *p, *a;
  215.  
  216.   t = new(tipoTabla);
  217.   t->letra = c;
  218.   t->bits = v;
  219.   t->nbits = l;
  220.  
  221.   if(!Tabla){
  222.      Tabla = t;
  223.      Tabla->sig = NULL;
  224.   }
  225.   else{
  226.       p = Tabla;
  227.       a = NULL;
  228.       while(p && p->letra < t->letra){
  229.          a = p;
  230.          p = p->sig;
  231.       }
  232.  
  233.       t->sig = p;
  234.       if(a) a->sig = t;
  235.       else Tabla = t;
  236.    }
  237. }
  238.  
  239. tipoTabla *BuscaCaracter(tipoTabla *Tabla, char c){
  240.   tipoTabla *t;
  241.  
  242.   t = Tabla;
  243.   while(t && t->letra != c) t = t->sig;
  244.   return t;
  245. }
  246.  
  247. void BorrarArbol(tipoNodo *n){
  248.   if(n->cero) BorrarArbol(n->cero);
  249.   if(n->uno)  BorrarArbol(n->uno);
  250.   delete(n);
  251. }

Ahora estuve viendo que la logica era comprimir por que coge solo un digito y si se repite a esta le aumenta la cantidad de veces en un apartado de frecuencias, entonces seguido seria pasarle al arbol, para que reduzca el tamanño en Bits.

Pero note que en una frase de 15 bits, esta llegaba a 72 Bits. (nom comprime ...)
Luego observe que el texto guardado ya no es legible, no se si esto se deba a las funciones archivos:
Código
  1.   fs = fopen(argv[2], "wb");
Lo asumi que tal vez este cifrado pero recorde que en archivos la escritura tambien se puede hacer en binario, cosa que aun no me queda, si deberia cifrar comprimir ?

A bueno puse algunas pruebas como resultados en este topic: Cifrando con Huffman - Duda

Saludos.
Páginas: [1] 2 3 4 5 6 7 8 9
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines