Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - rir3760

#661
Programación C/C++ / Re: Ayuda!!
9 Octubre 2013, 02:44 AM
Cita de: Xenomorfo77 en  8 Octubre 2013, 16:16 PM
Código (cpp) [Seleccionar]
*pointer++ = *pointer+POSITIONS-i-1;

...

2.- Al valor que haya en pointer le meto lo que haya en la ultima y despues se incrementa la posicion.
Esa sentencia tiene dos problemas importantes.

El primero es aplicar indirección y solo entonces sumar "POSITIONS-i-1", la sentencia termina procesada de esta forma:
Código (cpp) [Seleccionar]
*pointer++ = (*pointer) + POSITIONS - i - 1;
Cuando debería ser:
Código (cpp) [Seleccionar]
*pointer++ = *(pointer + POSITIONS - i - 1);

El otro se debe al uso del operador "++" y las dos instancias del objeto "pointer" en la expresión:
Código (cpp) [Seleccionar]
*pointer++ = *(pointer + POSITIONS - i - 1);
   (1)  (2)    (3)

Es un problema porque los lenguajes C y C++ no definen el orden de evaluación de los operandos de una expresión. Dependiendo del orden en que estos se evalúen y el momento en que se aplique el efecto lateral del operador "++" se pueden obtener diferentes resultados.

Lo mejor aquí es seguir la recomendación de eferion evitando expresiones excesivamente complicadas.

Un saludo
#662
And Operator (Visual Basic):
CitarIn a Boolean comparison, the And operator always evaluates both expressions, which could include making procedure calls. The AndAlso Operator (Visual Basic) performs short-circuiting, which means that if expression1 is False, then expression2 is not evaluated.

Un saludo
#663
Programación C/C++ / Re: Ayuda!!
8 Octubre 2013, 18:07 PM
Cita de: Xenomorfo77 en  8 Octubre 2013, 15:47 PMtengo que hacer un programa que le de la vuelta a un array pasandolo como argumento a una funcion.
Para invertir el array solo necesitas de un auxiliar y dos punteros (uno ya lo tienes, el parámetro de la función):
void turn(int *p)
{
   int *q;
   int aux;

   for (q = p + POSITIONS - 1; p < q; p++, q--){
      aux = *p;
      *p = *q;
      *q = aux;
   }
}


Un saludo
#664
Cita de: m@o_614 en  5 Octubre 2013, 04:57 AMlo unico que se me ocurrio fue hacer una lista doblemente ligada que es mas laboriosa, pero ps ya la empece, ahora tengo que terminarla.
Si en tu centro de estudios te piden que lo hagas de esa manera bueno, no tienes mas mas opción que hacerlo así pero no deja de ser una solución extremadamente complicada.

Cita de: m@o_614 en  5 Octubre 2013, 04:57 AMlo que hice fue leer el archivo al reves para que pudiera ingresar cada uno de los caracteres del archivo por la cabeza de una lista, porque si lo hubiera leido desde el principio tendria que buscar el fin de lista para ingresarle el caracter en su posicion correcta y era mas complicada por eso mejor alreves para que me ingresara en orden
Ya te había comentado en otro tema que no deberías utilizar fseek para posicionarte (en la forma que lo haces) en un stream en modo texto.

Soluciones realmente sencillas hay varias, supongamos que el archivo contiene los caracteres "ABCDE" y tu los insertas de la forma usual en la lista, esta contiene "EDCBA". Opciones:
A) Creas una función que invierta la lista, no mas de diez lineas de código.
B) Ya que la lista es de vinculo doble simplemente los procesas al revés empezando por el ultimo y terminando con el primero, para ello te mueves por la lista utilizando el puntero al nodo previo.

Cita de: m@o_614 en  5 Octubre 2013, 04:57 AMel problema que tengo es que en el typedef struct el dato lo tengo declarado como caracter, para ir ingresando caracter por caracter a la lista enlazada, pero despues una vez que recorro la lista busco  ' *',' + ', '/ ' y lo encuentra le pido que me haga un nodo que contenga la palabra que le corresponde, por ejemplo si es * la palabra sera _de_ pero esta seria una cadena y en el typedef la tengo declarada como un solo caracter, un char, como puedo solucionar esto?
Estas enfocando mal el problema. Supongamos que tu lista contiene los caracteres "Casa*Jose" y se debe expandir a "Casa de Jose" ahi los pasos son:
1) Iteras por cada nodo en la lista verificando si es un carácter especial.
2) Si el carácter es especial sustituyes el nodo (siguiendo el ejemplo) '*' por los nodos ' ', 'd', 'e' y ''.
En resumen no tienes que manejar distintos tipo de datos, solo expandir o contraer la lista.

Un saludo
#665
Cita de: edr89 en  6 Octubre 2013, 21:24 PMya tengo la version final, la funcion que borra los elementos es la adaptación del primero código al segundo
En esa función no necesitas de dos bloques ya que el segundo puede (y va) a procesar todos los nodos, a eso me refería con el comentario sobre evitar casos especiales.

Con solo el bloque necesario (el segundo) la función se reduce a:
void borrar_mayores(int natural)
{
   LISTPTR *p;
   LISTPTR aux;
   
   p = &first;
   while (*p != NULL)
      if ((*p)->ch > natural){
         aux = *p;
         *p = (*p)->next_rec;
         free(aux);
      }else
         p = &(*p)->next_rec;
}


Un saludo
#666
* Faltan los prototipos de la funciones "input_error" y "getch", si bien técnicamente no son errores se recomienda declarar toda función antes de su uso. En tu caso la solución es colocar el prototipo de "input_error" y la inclusión del encabezado conio al principio del programa.

* Cuando se desea imprimir un puntero se debe convertir este explícitamente al tipo "void *" y utilizar el especificador de formato "%p" con printf, estas dos sentencias en la función show_list:
printf("  %x   ", cur_ptr);
/* ... */
printf("      %x   \n", cur_ptr->next_rec);

Hay que sustituirlas por:
printf("  %p   ", (void *) cur_ptr);
/* ... */
printf("      %p   \n", (void *) cur_ptr->next_rec);


* En la función main debes utilizar nombres mas claros, en lugar de "rec_addr" y "add_to_list" los nombres "last" y "add_after" indican mejor el uso de la variable y función. Ahí la sentencia:
rec_addr = first;
Hay que eliminarla ya que el valor de "rec_addr" no se utiliza en el resto de la función.

* La función "input_error" siempre imprime el texto "Escribe el numero de datos a generar" y seria mejor reescribirla desde cero.

* Si ejecutas el programa varias veces te darás cuenta de que la eliminación de los nodos con un valor mayor al indicado no funciona correctamente.

Un saludo
#667
Cita de: zagato-krono en  5 Octubre 2013, 02:26 AMEl programa consiste en ordenar el vector por edad y nombre alfabeticamente...
En el segundo fragmento que debes completar solo tienes un bucle cuando necesitas dos.

En el primer fragmento hay dos errores, el primero ya lo indico eferion y el segundo son los indices (incorrectos) utilizados. Utiliza el motor de búsqueda de los foros (o sitios como Wikipedia) para verificar como se debe implementar el algoritmo de ordenacion BubbleSort.

Un saludo
#668
Algo que falta en tu programa es la inclusión de los encabezados <stdio.h> y <stdlib.h>.

El primer error importante se encuentra en el bucle donde creas la lista con números aleatorios:
for (i = 0; i < respuesta_num; i++){
   nodo = (st_num *) malloc(sizeof(st_num));
   
   nodo->rand_num = rand() % 100 + 1;
   if (i == 0){
      fila.head = nodo;
      fila.last = nodo;
      nodo->ptr_next = NULL;
   }
   if (nodo->ptr_next != NULL){ /* <== */
      nodo ->ptr_next = fila.head;
   }
   fila.head = nodo;
   printf ("%d\n", nodo->rand_num);
}

Al reservar memoria con malloc el contenido del bloque es "no definido", puede ser cualquier valor incluyendo NULL (0 en contexto de punteros). En otras palabras no hay garantías de que el campo "ptr_next" en los nodos después del primero se ajuste correctamente.

Ese bucle se debe cambiar a:
   for (i = 0; i < respuesta_num; i++){
      nodo = malloc(sizeof *nodo);
      nodo->rand_num = rand() % 100 + 1;
     
      if (i == 0){
         fila.last = nodo;
         nodo->ptr_next = NULL;
      }else
         nodo ->ptr_next = fila.head;
      fila.head = nodo;
      printf ("%d\n", nodo->rand_num);
   }


En cuanto al bloque donde se eliminan los elementos mayores al indicado este tiene varios errores graves ya que el programa va a reventar con una lista vacía y también si la lista contiene un solo nodo y este debe eliminarse. Otro detalle ahí es que no verificas si se debe eliminar el primer nodo.

Una forma de eliminar todos los nodos cuyo valor sea mayor que el indicado es utilizando un puntero de tipo "st_num **p" con la ventaja de que este permite evitar el caso especial del primer nodo. Tu programa con los cambios:
#include <stdio.h>
#include <stdlib.h>

typedef struct st_num {
   int rand_num;
   struct st_num *ptr_next;
} st_num;

struct {
   st_num *head;
   st_num *last;
   
} fila;

void menu_principal(void);

int main(void)
{
   int i;
   int respuesta_num;
   char key_buff[40];
   st_num *nodo;
   st_num **p;
   
   menu_principal();
   scanf("%d", &respuesta_num);
   gets(key_buff);
   
   for (i = 0; i < respuesta_num; i++){
      nodo = malloc(sizeof *nodo);
      nodo->rand_num = 1 + rand() % 2;
     
      if (i == 0){
         fila.last = nodo;
         nodo->ptr_next = NULL;
      }else
         nodo ->ptr_next = fila.head;
      fila.head = nodo;
   }
   
   i = 0;
   for (nodo = fila.head; nodo != NULL; nodo = nodo->ptr_next, i++)
      printf(" %d", nodo->rand_num);
   printf(" (%d)\n", i);
   
   printf("Ahora escribe un numero natural menor a 100: ");
   scanf("%d", &respuesta_num);
   gets(key_buff);
   
   /* Eliminamos todos los nodos mayores que "respuesta_num" */
   p = &fila.head;
   while (*p != NULL)
      if ((*p)->rand_num > respuesta_num){ /* Eliminar actual */
         nodo = *p;
         *p = (*p)->ptr_next;
         free(nodo);
      }else /* Siguiente nodo */
         p = &(*p)->ptr_next;
   /* Ajustamos el valor del campo fila.last */
   if (fila.head == NULL)
      fila.last = NULL;
   else {
      fila.last = fila.head;
      while (fila.last->ptr_next != NULL)
         fila.last = fila.last->ptr_next;
   }
   
   i = 0;
   for (nodo = fila.head; nodo != NULL; nodo = nodo->ptr_next, i++)
      printf(" %d", nodo->rand_num);
   printf(" (%d)\n", i);
   
   return 0;
}

void menu_principal(void)
{
   system ("CLS");
   puts ("Generador de numeros aleatorios\n\n");
   printf ("Escribe el numero de datos a generar: ");
}


Por ultimo deberías evitar el uso de la función gets, mas información en la pagina |Lo que no hay que hacer en C/C++. Nivel basico|.

Un saludo
#669
En tu caso descomprimir es todavía mas fácil ya que solo debes verificar si el carácter se debe imprimir tal cual o en su lugar se debe imprimir una cadena. Para eso lo mas sencillo es utilizar una tabla de valores.

Por ejemplo:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /* UCHAR_MAX */

int main(void)
{
   char linea[] = "El libro*Mary es/la clase*mate+la maestra Ana";
   
   char ch[UCHAR_MAX] = {0};
   char set[] = "*/+-@";
   char *cadena[] = {" de "," para "," con "," desde "," al "};
   int i;
   int pos;
   
   /* Los caracteres especiales toman valores mayores que cero */
   for (i = 0; set[i] != '\0'; i++)
      ch[set[i]] = i + 1;
   
   for (i = 0; linea[i] != '\0'; i++){
      pos = ch[linea[i]];
     
      if (pos)
         printf("%s", cadena[pos - 1]);
      else
         putchar(linea[i]);
   }
   putchar('\n');
   
   return EXIT_SUCCESS;
}


Un saludo
#670
En esta función:
Código (cpp) [Seleccionar]
Prueba* pPrueba()
{
   Prueba ejemplo1;
   return &ejemplo1;
}

Estas retornando la dirección de una variable local, no es valido ya que todas las variables locales se destruyen al finalizar la función.

Para que compile sin problemas puedes calificar la variable "ejemplo1" con static, de esa forma la variable existe durante toda la duración del programa:
Código (cpp) [Seleccionar]
Prueba* pPrueba()
{
   static Prueba ejemplo1;
   return &ejemplo1;
}


Con todo el ejemplo solo tiene caso (sentido) para practicar el uso de funciones y sus valores de retorno.

Un saludo