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

#511
Cuando tengas una duda por favor indica el lenguaje de programacion.

En el caso de C ...

Cita de: m@o_614 en 12 Enero 2014, 03:15 AMpor que en algunas ocasiones se tienen que pasar los punteros por referencias?
Porque en C todo se pasa por valor.

Si se declara en la funcion "f" una variable "a" y se quiere modificar esta en otra funcion "g" se debe emular el paso por referencia. Eso aplica sin importar el tipo de la variable.

Cita de: m@o_614 en 12 Enero 2014, 03:15 AMcuando estas haciendo una lista enlazada y quieres insertar por la cabeza, por que tienes que pasar el puntero por referencia
Veamos:

1) Declaras en la funcion main la variable "primero" y esta almacena la direccion en memoria del primer nodo (por eso es un puntero).
2) Defines una funcion "insertar" y debe tener la capacidad de insertar en cualquier lugar, incluso modificando cual sera el primer nodo y por ello debe tener la capacidad de modificar una variable de otra funcion (la variable "primero" de la funcion main).

Es debido al punto 2 que debe pasarse su direccion en memoria.

Cita de: m@o_614 en 12 Enero 2014, 03:15 AMno se supone que el puntero ya almacena una direccion de memoria
Si pero lo que se necesita no es poder modificar el primer nodo sino modificar la variable que almacena ese valor (la variable "primero" de main).

Un ejemplo para explicarlo mejor:
#include <stdio.h>
#include <stdlib.h>

void fn(int **pa_p, int **pa_q);

int main(void)
{
   int a = 1;
   int b = 9;
   
   /* "p" apunta a "a", "q" apunta a "b" */
   int *p = &a;
   int *q = &b;
   
   /* Imprimimos los valores de los objetos apuntados */
   printf("%d %d\n", *p, *q);
   
   /* Se intercambian los valores de las variables "p" y "q" */
   fn(&p, &q);
   
   /* Imprimimos los valores de los objetos apuntados */
   printf("%d %d\n", *p, *q);
   
   return EXIT_SUCCESS;
}

void fn(int **pa_p, int **pa_q)
{
   int *aux;
   
     aux = *pa_p;
   *pa_p = *pa_q;
   *pa_q = aux;
}


Un saludo
#512
No se recomienda utilizar fflush(stdin), las razones se describen en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.

Alternativas hay varias, puedes utilizar el motor de búsqueda para revisar los temas relacionados con el bufer de la entrada estándar.

Un saludo
#513
Cita de: dennis094 en 16 Enero 2014, 23:22 PM¿en c hay alguna funcion como en java con la funcion "puts" que te permitia agregar un objeto (en este caso un struct) al array?
No.

En C la operación debe hacerse manualmente, lo usual es tener un array del tamaño "apropiado" y un contador del numero de elementos utilizados. Para agregar el elemento simplemente se asigna y se incrementa el contador, por ejemplo:
struct cadena {
   char *ch;
   size_t num_chars;
};

/* ... */

struct cadena linea[100];
size_t num_lineas = 0;
struct cadena aux;

/* ... */

/* Agregamos manualmente una linea (almacenada en el auxiliar) */
linea[num_lineas] = aux;
num_lineas++;


Un saludo
#514
Lo primero que debes hacer es cambiar colocar la declaración de la estructura antes de la declaración del array:
struct persona{

   char nombre[30];
   char apellidoP[30];
   char apellidoM[30];
   char rut[20];
   int edad;   

};

struct persona personas[10];


El porque se "salta" la lectura del nombre se debe a que estas intercalando llamadas a gets (no deberías, en su lugar fgets) y scanf, el tema se ha tratado en los foros y solo es cuestión de utilizar el motor de búsqueda.

Para solucionarlo debes eliminar el resto de la linea después de cada llamada a scanf (y antes de una llamada a fgets), por ejemplo la función "menuPrincipal" se debe cambiar a:
void menuPrincipal(void)
{
   int opcion;
   int ch;
   
   puts("::::: MENU PRINCIPAL :::::");
   puts("1.- Ingresar nueva persona");
   puts("2.- Informacion de personas inscritas");
   puts("3.- Salir");
   puts("Digite su opcion: ");

   scanf("%i", &opcion);
   /* Descartamos el resto de la linea */
   while ((ch = getchar()) != EOF && ch != '\n')
      ;
   
   switch(opcion){
   case 1:
      ingresarPersona();
      break;
   case 2:
      desplegarDatos();
      break;
   case 3:
      flag = false;
      break;
   }   
}

El cambio en la función "ingresarPersona" es similar.

El porque no se imprimen los datos correctamente se debe al bucle de la función "desplegarDatos":
void desplegarDatos(void)
{
   int i;
   
   puts("Desplegando datos personales de los registrados:");
   for(i = 0; i < cant; i++){
      printf("\n\nNombre: %s",personas[cant].nombre);
      printf("\nApellido paterno: %s",personas[cant].apellidoP);
      printf("\nApellido materno: %s",personas[cant].apellidoM);
      printf("\nRut: %s",personas[cant].rut);
      printf("\nEdad: %i\n",personas[cant].edad);
   }
}

En el cuerpo de este utilizas "personas[ cant ]" cuando debería ser "personas[ i ]".

Un saludo
#515
Lo primero que debes hacer es evitar el uso de gets y fflush(stdin), las razones de ello se explican en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.

El problema se debe (como indicas) a que la sintaxis que utilizas en la función "leer" no es la correcta. En esa función no necesitas de una variable auxiliar ya que puedes utilizar directamente el elemento del array "arrayPersonas".

Si incluimos el encabezado <string.h> y modificamos la función:
#include <string.h>

/* ... */

void leer(int num)
{
   int i;
   int ch;
   char *p;
   
   for (i = 0; i < num; i++){
      puts("Nombre:");
      fgets(arrayPersonas[i].nombre, 50, stdin);
      /* Eliminamos (si existe) el avance de linea del nombre */
      if ((p = strchr(arrayPersonas[i].nombre, '\n')) != NULL)
         *p = '\0';
     
      puts("Apellido:");
      fgets(arrayPersonas[i].apellido, 50, stdin);
      /* Eliminamos (si existe) el avance de linea del apellido */
      if ((p = strchr(arrayPersonas[i].apellido, '\n')) != NULL)
         *p = '\0';
     
      puts("Sexo:");
      scanf("%c", &arrayPersonas[i].sexo);
     
      /* Descartamos el resto de la linea */
      while ((ch = getchar()) != EOF && ch != '\n')
         ;
   }
}

El programa funcionara correctamente. Por ultimo hay que eliminar la variable "p":
persona p;
Ya que no se utiliza en el programa.

Un saludo
#516
Programación C/C++ / Re: Lista con arrays
16 Enero 2014, 02:12 AM
Ya te había comentado en otros temas que utilizar fseek en un archivo abierto en modo texto no es una buena idea.

El error que mencionas se genera en las lineas:
calculado[i] = Tabla_Operandos(hc12);
...
calcular[i] = Tabla_Operandos(hc12);
...
total[i] = Tabla_Operandos(hc12);

Y se genera porque "calculado[ i ]", "calcular[ i ]" y "total[ i ]" son (expresiones) de tipo char mientras que el tipo de retorno de la función "Tabla_Operandos" es "char *".

Un saludo
#517
Cita de: NOB2014 en 14 Enero 2014, 23:12 PM¿tiene sentido hacer este mismo código con punteros
Ya los estas utilizando. El operador "[]" es uno binario y requiere que uno de sus operandos (no importa cual) sea un puntero.

Cita de: NOB2014 en 14 Enero 2014, 23:12 PMteniendo en cuenta que el nombre de un arreglo es un apuntador, o el nombre de un arreglo es la dirección del primer elemento que contiene el arreglo?
No exactamente.

El identificador de un array usualmente resulta en la dirección en memoria de (un puntero a) su primer elemento, por ejemplo al utilizar los operadores "[]" y "*". En tu caso:
copia[j] = enteros[i];

/* La forma equivalente utilizando el operador "*": */
*(copia + j) = *(enteros + i);


Una de las excepciones es el operador sizeof, en tu caso:
longitud = sizeof enteros / sizeof *enteros;
Da el resultado correcto porque la primera instancia de "enteros" denota (referencia) al array y resulta en el numero de bytes utilizados para almacenarlo.

Un saludo
#518
Programación C/C++ / Re: ayuda codigo c
12 Enero 2014, 18:53 PM
Si estas leyendo un manual este debería indicar antes o después del ejemplo la intención y operación de las llamadas empezando por fork.

En cuanto al programa este solo verifica si se pasa al menos un argumento, si es así llama primero a fork para crear un proceso hijo y a continuación ejecuta el programa indicado mediante execvp.

Un saludo
#519
Cita de: NOB2014 en  6 Enero 2014, 21:45 PMlo que quiero saber es si se puede antes de convertir la cadena a entero verificar si el número ingresado sobrepasa el máximo permitido por el tipo int.
Para realizar esa operación puedes utilizar la función strtol (prototipo en <stdlib.h>), por ejemplo:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>

#define NUM_CHARS  256

int main(void)
{
   char cad[NUM_CHARS];
   char *p;
   long num;
   
   printf("Introduce un numero (%d .. %d): ", INT_MIN, INT_MAX);
   fflush(stdout);
   if (fgets(cad, NUM_CHARS, stdin) == NULL)
      return EXIT_FAILURE;
   
   num = strtol(cad, &p, 10);
   
   if (num == 0 && p == cad)
      puts("Entrada no valida");
   else if (errno == ERANGE && (num == LONG_MAX || num == LONG_MIN))
      puts("Numero fuera del rango valido para el tipo signed long");
   else {
      while (isspace(*p))
         p++;
     
      if (*p != '\0')
         puts("Caracteres invalidos al final de la cadena");
      else
         printf("El numero %ld es valido\n", num);
   }
   
   return EXIT_SUCCESS;
}

Solo falta agregar una validación (que el numero este en el rango INT_MIN .. INT_MAX).

Un saludo
#520
Si revisamos con cuidado el enunciado este indica que la función debe realizar las tres tareas (obtener el primer dígito, el numero de estos y su suma) y retornarlos lo que implica utilizar el valor de retorno de la función y dos parámetros de salida.

Una forma de implementarla utilizando el tipo div_t y la función div es:
#include <stdlib.h>

int fn(int num, int *digitos, int *suma)
{
   div_t r;
   
   *digitos = *suma = 0;
   do {
      r = div(num, 10);
     
      *suma += r.rem;
      ++*digitos;
   }while ((num = r.quot) != 0);
   
   return r.rem; /* Se retorna el ultimo digito */
}

Es en la función main donde se deben leer los números, llamar a la función e imprimir el numero si se cumplen las condiciones.

----

Cita de: SoyelRobert en  6 Enero 2014, 14:31 PMRespecto a lo de la funcion main tipo int... si la verdad es que ya lo explicaste en otro hilo y soy consciente de ello, solamente que lo he hecho así por vago y ahorrar el return.

Sobre lo de indentar el codigo, tambien estoy consciente de ello... la verdad es que desde un principio no lo he hecho y ahora me va a costar acostumbrarme.
La intención de que te apegues al estándar y que indentes el código es darnos todas las facilidades para resolver la dudas que se presentan, así cada quien pone su parte.

Y para indentar el código fuente cualquier IDE o PTE que se apegue a lo natural y las buenas costumbres debe ser capaz de, al menos, indentar el código fuente conforme este se introduce. También (y esto ya lo comento amchacon) puedes utilizar una aplicación que haga el trabajo por ti, por ejemplo astyle.

----

Por ultimo la función scanf retorna el numero de conversiones realizadas con éxito o, si no se realizo ninguna debido a error o fin de archivo, el valor EOF. Por ello para verificar si se leyó con éxito un entero diferente de cero se debe utilizar:
while (scanf("%d", &num) == 1 && num != 0) ...

Un saludo