elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
29 Mayo 2012, 02:57  


Tema destacado: [AIO elhacker.NET] Compilación herramientas análisis y desinfección malware

+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  problemas con punteros
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: problemas con punteros  (Leído 351 veces)
m@o_614

Desconectado Desconectado

Mensajes: 35


Ver Perfil
problemas con punteros
« en: 4 Enero 2012, 20:15 »

tengo un problema con este codigo que me tiene que ingresar un maximo de 20 registros con listas enlazadas, no se si lo estoy haciendo bien :rolleyes: no se si tengo que definir un nuevo tipo, algo asi como :

ingreso ingresos, y despues pasarle el apuntador ingreso*pIngreso y pasarle la direccion pIngreso=&ingresos :o

Código
#include <stdio.h>
#include <stdlib.h>//funcion malloc()
#include <conio.h> // funcion getch()
#include <string.h> // funcion strcpy()
#define  MAX_REG 20 //Define el maximo numero de registros
 
// Primero definimos los tipos
typedef struct registro1
{
   char concepto[30+1];
   char RFC[21+1];
   float monto;
   int mes;
   struct registro1* sig;
 
}ingreso;
 
int introduceRegistro(ingreso *pIngreso);//le pasamos el puntero original de la lista
 
int main()
{
   ingreso *pIngreso;
   printf("\nIngresa los datos del registro \n");
   introduceRegistro(pIngreso);//Aqui todavia no estoy segura de ponerle el ampersand, porque me marca un warning:passing arg 1 of `introduceRegistro´ from incompatible pointer type
 
   getch();
   return 0;
}
 
int introduceRegistro(ingreso *pIngreso)
{
   int i;
   for(i=0,pIngreso->sig==NULL;i<MAX_REG;i++,pIngreso=pIngreso->sig)
   {
       pIngreso=(ingreso*)malloc(sizeof(ingreso));//A todo puntero hay que asignarle memoria.
       printf("Concepto :");
       fflush(stdin);
       gets(pIngreso->concepto);
       printf("RFC :");
       fflush(stdin);
       gets(pIngreso->RFC);
       printf("Monto :");
       fflush(stdin);
       scanf("%f",&pIngreso->monto);
       printf("Mes :");
       fflush(stdin);
       scanf("%d",&pIngreso->mes);
   }
return 0;
}
 


En línea
_Enko


Desconectado Desconectado

Mensajes: 301



Ver Perfil
Re: problemas con punteros
« Respuesta #1 en: 4 Enero 2012, 22:05 »

No soy bueno con esto de C, pero me parece qeu tienes problema en el for
Código
for(i=0,pIngreso->sig==NULL;i<MAX_REG;i++,pIngreso=pIngreso->sig)
{
       pIngreso=(ingreso*)malloc(sizeof(ingreso));//A todo puntero hay que asignarle memoria.
 
pIngreso=pIngreso->sig....

pIngreso->sig siempre vale NULL en tu codigo, no apunta a ningun lado nunca.
a lo sumo seria al reves.
Para que funcione el for, tendria que ser
Código
 pIngreso->sig = pIngreso
 

No es la misma inicializacion para el primer elemento de la lista que para los siguientes, deberia ir fuera del bucle.
Código
pIngreso=(ingreso*)malloc(sizeof(ingreso));
for(i=0; i<MAX_REG; i++)
   {
pIngreso->valores = etc...
//modificamos valores pIngreso
 
//reservamos espacio para el elemento siguiente
//y aprovechamos para enlazarlo en la lista
       pIngreso->sig =(ingreso*)malloc(sizeof(ingreso));
//al final del bucle
//asignamos el elemento siguiente al actual
//para volver a trabajar con el nuevo elemento
pIngreso = pIngreso->sig
 
   }
 


« Última modificación: 4 Enero 2012, 22:16 por _Enko » En línea


Servicio tecnico Blackberry http://www.serviciotecnicocelular.com
Didacso

Desconectado Desconectado

Mensajes: 202



Ver Perfil
Re: problemas con punteros
« Respuesta #2 en: 4 Enero 2012, 22:13 »

Hola , he revisado y cambiado algunas cosas de tu código, míratelo y comentamos lo que no comprendas ...

Por cierto , por si están tentados a comentar el tema recursividad usada en el programa, no se molesten,  tengo bastante claros los pros y contras ... en este caso la use solo para el ejemplo

Código
#include <stdio.h>
#include <stdlib.h>//funcion malloc()
//no debes usar nunca conio
//#include <conio.h> // funcion getch()
#include <string.h> // funcion strcpy()
#define  MAX_REG 2 //Define el maximo numero de registros
 
//limpia el buffer
#define LIMPIAR_BUFFER while(getchar() != '\n')
 
// Primero definimos los tipos
typedef struct registro1
{
   char concepto[30+1];
   char RFC[21+1];
   float monto;
   int mes;
   struct registro1* sig;
 
}ingreso;
 
int introduceRegistro(ingreso **pIngreso);//le pasamos el puntero original de la lista
 
//agrega un elemento a la lista
void addIngreso(ingreso **pIngreso , ingreso *aux );
 
//imprime el campo concepto de todos los elementos en la lista
void imprimeConcepto(ingreso *pIngreso);
 
 
int main()
{
   ingreso *pIngreso = NULL;
   printf("\nIngresa los datos del registro \n");
   introduceRegistro(&pIngreso);
 
   printf("presiona una tecla para continuar...\n") ;
   getchar();
   return 0;
}
 
void addIngreso(ingreso **pIngreso , ingreso *aux ){
if(*pIngreso == NULL){
*pIngreso = aux;
}else{
//llamamos recursivamente a la función
addIngreso(&((*pIngreso)->sig) , aux);
}
}
 
void imprimeConcepto(ingreso *pIngreso){
if(pIngreso != NULL){
printf("%s \n", pIngreso->concepto);
imprimeConcepto(pIngreso->sig);
}
}
 
int introduceRegistro(ingreso **pIngreso)
{
   int i;
   //lo usamos para ir agregando la información
   ingreso *aux;
 
   for(i=0 ;  i<MAX_REG ; i++ ){    
       aux = (ingreso*)malloc(sizeof(ingreso));//A todo puntero hay que asignarle memoria.
 
       printf("Concepto :");
       gets(aux->concepto);
 
       printf("RFC :");
       gets(aux->RFC);    
 
       printf("Monto :");
       scanf("%f",&aux->monto);
       LIMPIAR_BUFFER;      
 
       printf("Mes :");
       scanf("%d",&aux->mes);
LIMPIAR_BUFFER;
 
       //lo agregamos a la lista
       addIngreso(pIngreso, aux);
   }
 
   printf("Los valores del campo concepto de la lista de ingresos son : \n");
  //mostramos el "concepto" de todos los campos
  imprimeConcepto(*pIngreso);
 
return 0;
}
 

Saludos
En línea

Nadie alcanza la meta con un solo intento, ni perfecciona la vida con una sola rectificación, ni alcanza altura con un solo vuelo.
BlackZeroX (Astaroth)
Wiki

Desconectado Desconectado

Mensajes: 2.831


I'Love...!¡.


Ver Perfil WWW
Re: problemas con punteros
« Respuesta #3 en: 4 Enero 2012, 22:37 »

Modifique un poco tu codigo...

A por cierto conio.h es solo bajo Windows... pero tu decide si la quieres o no usar.

Código
 
#include <stdio.h>
#include <stdlib.h>//funcion malloc()
#include <string.h> // funcion strcpy()
 
#define MAX_REG 20 //Define el maximo numero de registros
#define MAX_CONCEPTO 30+1
#define MAX_RFC 21+1
 
 
// Primero definimos los tipos
typedef struct registro1
{
   char concepto[MAX_CONCEPTO];
   char RFC[MAX_RFC];
   float monto;
   int mes;
   struct registro1* next;
 
}INGRESO,   //  Tipo..
*LPINGRESO; //  Puntero a un Tipo en lugarde esrbir *INGRESO se escribe LPINGRESO
 
LPINGRESO introduceRegistro(LPINGRESO lpIngreso, int* iCount, int iMaxReg, int addIn);//le pasamos el puntero original de la lista
int releaseIngresos(LPINGRESO lpIngreso);
LPINGRESO getLastIngreso(LPINGRESO lpIngreso);
 
int main()
{
   LPINGRESO lpIngreso = NULL;
   printf("\nIngresa los datos del registro \n");
 
   lpIngreso = introduceRegistro(lpIngreso,    //  Empesamos desde este registro... obviamente como es NULL creara un nuevo registro...
                                 NULL,
                                 MAX_REG,
                                 1);
   printf("%d\n", releaseIngresos(lpIngreso));
   getchar();
 
   return EXIT_SUCCESS;
}
 
//  Libera TODOS LOS NODOS siguientes de INGRESO...
int releaseIngresos(LPINGRESO lpIngreso)
{
   int iRet = 0;
 
   if (lpIngreso)
   {
       iRet = 1 + releaseIngresos(lpIngreso->next);    //  Liberamos los hijos...
       free(lpIngreso);                            //  Liberamos...
   }
   return iRet;
}
 
//  Retorna el ultimo registro...
LPINGRESO getLastIngreso(LPINGRESO lpIngreso)
{
   if (lpIngreso)
       while (lpIngreso->next)
           lpIngreso = lpIngreso->next;
   return lpIngreso;
}
 
/// La funci&#243;n va a retornar un LPINGRESO al 1er elemento INGRESO...
LPINGRESO introduceRegistro(LPINGRESO lpIngreso,    //  Lista desde donde se empesara a crear...
                           int* iCount,            //  Ouput Retorna la cantidad de registros creados...
                           int iMaxReg,            //  MAXIMO de registros a crear...
                           int addIn)              //  Si lpIngreso->next apunta a otro registro, los registros a crear se deben insertarse:
                                                   //  -1 Creamos lo registros entre lpIngreso y lpIngreso->next...
                                                   //  0 Eliminar TODOS apartir de lpIngreso->next e insertar los nuevos.
                                                   //  1 Inserta los registros al final al final de la lista.
                                                   //  Se ignora este parametro si lpIngreso es NULL.
{
   int i = 0;
   LPINGRESO lpNewIngreso = NULL;
   LPINGRESO lpNextStaticIngreso = NULL;
   LPINGRESO lpFirtsIngreso = lpIngreso;
 
   /// Si lpIngreso ya tiene otros registros enlazados podemos hacer tres cosas
   if (lpIngreso)
       switch(addIn)
       {
           case -1:    //  Agregamos los nuevos seguido a lpIngreso pero antes de lpIngreso->next
               lpNextStaticIngreso = lpIngreso->next;
               break;
 
           case 0:     //  Eliminamos TODOs lo registros desde lpIngreso->next...
               releaseIngresos(lpIngreso->next);
               break;
 
           default:    //  Buscamos el ultimo de la lista y empesamos a agregarlos apartir de este.
               lpIngreso = getLastIngreso(lpIngreso);
               break;
       }
 
   for(i = 0
       //, lpIngreso->next == NULL ->> No tiene caso comprobar con NULL... creo que querias asignarle NULL, &#191;no?.
       ;i < iMaxReg;  //  Cantidad de registros...
       i++)           //  Contador creciente en 1.
   {
       lpNewIngreso = (LPINGRESO)malloc(sizeof(INGRESO));
 
       if (!lpNewIngreso)  //  Se reservo la memoria deseada?...
           break;  //  Salimos del for()...
 
       memset(lpNewIngreso, 0, sizeof(INGRESO));   //  Limpiamos el bloque de memoria...
 
       if (!lpFirtsIngreso)
           lpFirtsIngreso = lpNewIngreso;
 
       //  Enlazamos con el anterior...
       if (lpIngreso)
           lpIngreso->next = lpNewIngreso;
 
       lpIngreso = lpNewIngreso;
 
       /// El llenado de datos se puede hacer despues de haber creado los elementos...
       /*
       fprintf(stdout, "Concepto:\n");
       fgets(lpIngreso->concepto, MAX_CONCEPTO - 1, stdin);    //  Hay que leer solo la longitud requerida...
 
       fprintf(stdout, "RFC:\n");
       fgets(lpIngreso->concepto, MAX_RFC - 1, stdin);    //  Hay que leer solo la longitud requerida...
 
       fprintf(stdout, "Monto:\n");
       scanf("%f", &lpIngreso->monto);
 
       fprintf(stdout, "Mes:\n");
       scanf("%d", &lpIngreso->mes);
       */

   }
 
   if (iCount)
       (*iCount) = i;
 
   lpIngreso->next = lpNextStaticIngreso;
 
   return lpFirtsIngreso;
}
 
 

Dulces Lunas!¡.
« Última modificación: 4 Enero 2012, 23:00 por BlackZeroX (Astaroth) » En línea

Web Principal-->[ Blog(VB6) | Host File (Public & Private) | Scan Port | (New)MyInfraPC (Descubre mi Contraseña venefi. $) ]



The Dark Shadow is my passion.
El infierno es mi Hogar, mi novia es Lilith y el metal mi
m@o_614

Desconectado Desconectado

Mensajes: 35


Ver Perfil
Re: problemas con punteros
« Respuesta #4 en: 14 Enero 2012, 02:43 »

no entiendo por que usas doble puntero  :o ????
En línea
Xandrete

Desconectado Desconectado

Mensajes: 195



Ver Perfil
Re: problemas con punteros
« Respuesta #5 en: 14 Enero 2012, 12:10 »

¡Hola m@o_614 (y al resto  ;D)!

Yo me imagino que utiliza dobles punteros porque en C no se puede pasar parámetros por referencia con el & a las funciones (eso es algo nuevo de C++), así que para lograr lo mismo, lo que se hace es pasar un puntero al dato que querías que se modificara dentro de la función (de hecho, eso es lo que hace internamente C++). Como has dicho lo de pasar el parámetro con el ampersand (&) en los comentarios de tu código, yo me he imaginado que el código era para C++, pero luego veo el resto y compruebo que es un código típicamente C, así que no sé interpretar muy bien si lo quieres para C estricto o si se pueden incorporar novedades C++.

Si estás programando en C++ tienes cositas para facilitarte la vida. Por ejemplo, en lugar de usar malloc, puedes usar el operador new (y te ahorras incluir una librería). Por otro lado, puedes usar la librería string de C++ en lugar de la librería de C. Una de sus principales ventajas es que te permite usar un objeto string que te evita lidiar con tamaños de arrays y demás "basura" (lo digo cariñosamente  ;D) que te aleja de lo que es la solución al problema en sí mismo. Por otro lado, te recomendaría restringirte a la librería estándar para estas cosas (lo digo por lo de conio). Y también te diría que no usaras fflush para limpiar el buffer de entrada (explicación de estos dos últimos consejos en uno de los post con chincheta de este mismo foro: http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html). De todas formas, eso es harina de otro costal. Lo que importa aquí son los punteros, ¿no  :D?

Yo también he hecho mi propia versión del programa (pero en C++):

Código
#include <iostream>
#include <string>
#define  MAX_REG 20
using namespace std;
 
struct Ingreso {
string concepto;
string RFC;
float monto;
int mes;
Ingreso* sig;
 
};
 
void rellenarDatos(Ingreso* ing) {
cout << "Concepto: ";
cin >> ing->concepto;
cout << "RFC: ";
cin >> ing->RFC;
cout << "Monto: ";
cin >> ing->monto;
cout << "Mes: ";
cin >> ing->mes;
}
 
Ingreso* agregarIngreso(Ingreso* ultimoIngreso) {
Ingreso* siguienteIngreso;
if (ultimoIngreso == NULL) siguienteIngreso = new Ingreso;
else siguienteIngreso = ultimoIngreso->sig = new Ingreso;
rellenarDatos(siguienteIngreso);
return siguienteIngreso;
}
 
Ingreso* introduceRegistro() {
int i;
Ingreso* pIngreso;
Ingreso* ultimoIngreso;
pIngreso = ultimoIngreso = agregarIngreso(NULL);
for(i=1;i<MAX_REG;++i)
ultimoIngreso = agregarIngreso(ultimoIngreso);
ultimoIngreso->sig = NULL;
return pIngreso;
}
 
int main() {
cout << "Ingresa los datos del registro" << endl;
Ingreso* pIngreso = introduceRegistro();
/* ... */
}

No me preocupado por el tema de la entrada de datos mucho. Para controlar el tema del buffer de entrada y estas "tonterías" (cariñosamente otra vez) sólo habría que tocar la rutina rellenarDatos.

Por cierto, BlackZeroX, "peaso" código, ¿no  :rolleyes:?

¡Saludacos!

En línea
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
punteros c++
Programación C/C++
wise 12 2,251 Último mensaje 3 Octubre 2006, 23:47
por winfuck
problemas con punteros
Programación C/C++
kamsky 2 502 Último mensaje 19 Abril 2007, 22:25
por kamsky
Problema con punteros a punteros
Programación C/C++
jion 4 508 Último mensaje 28 Febrero 2009, 17:33
por jion
Problemas con funciones y punteros
Programación C/C++
kondrag_X1 10 1,172 Último mensaje 20 Noviembre 2009, 21:39
por xtermsh
Problemas con punteros en listas.
Programación C/C++
samur88 6 2,041 Último mensaje 10 Enero 2011, 00:09
por samur88
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines