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

 

 


Tema destacado: Guía actualizada para evitar que un ransomware ataque tu empresa


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  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 2,510 veces)
m@o_614


Desconectado Desconectado

Mensajes: 389


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

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
  1. #include <stdio.h>
  2. #include <stdlib.h>//funcion malloc()
  3. #include <conio.h> // funcion getch()
  4. #include <string.h> // funcion strcpy()
  5. #define  MAX_REG 20 //Define el maximo numero de registros
  6.  
  7. // Primero definimos los tipos
  8. typedef struct registro1
  9. {
  10.    char concepto[30+1];
  11.    char RFC[21+1];
  12.    float monto;
  13.    int mes;
  14.    struct registro1* sig;
  15.  
  16. }ingreso;
  17.  
  18. int introduceRegistro(ingreso *pIngreso);//le pasamos el puntero original de la lista
  19.  
  20. int main()
  21. {
  22.    ingreso *pIngreso;
  23.    printf("\nIngresa los datos del registro \n");
  24.    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
  25.  
  26.    getch();
  27.    return 0;
  28. }
  29.  
  30. int introduceRegistro(ingreso *pIngreso)
  31. {
  32.    int i;
  33.    for(i=0,pIngreso->sig==NULL;i<MAX_REG;i++,pIngreso=pIngreso->sig)
  34.    {
  35.        pIngreso=(ingreso*)malloc(sizeof(ingreso));//A todo puntero hay que asignarle memoria.
  36.        printf("Concepto :");
  37.        fflush(stdin);
  38.        gets(pIngreso->concepto);
  39.        printf("RFC :");
  40.        fflush(stdin);
  41.        gets(pIngreso->RFC);
  42.        printf("Monto :");
  43.        fflush(stdin);
  44.        scanf("%f",&pIngreso->monto);
  45.        printf("Mes :");
  46.        fflush(stdin);
  47.        scanf("%d",&pIngreso->mes);
  48.    }
  49. return 0;
  50. }
  51.  


En línea

_Enko


Desconectado Desconectado

Mensajes: 538



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

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

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


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

Gallu

Desconectado Desconectado

Mensajes: 247



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

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
  1. #include <stdio.h>
  2. #include <stdlib.h>//funcion malloc()
  3. //no debes usar nunca conio
  4. //#include <conio.h> // funcion getch()
  5. #include <string.h> // funcion strcpy()
  6. #define  MAX_REG 2 //Define el maximo numero de registros
  7.  
  8. //limpia el buffer
  9. #define LIMPIAR_BUFFER while(getchar() != '\n')
  10.  
  11. // Primero definimos los tipos
  12. typedef struct registro1
  13. {
  14.    char concepto[30+1];
  15.    char RFC[21+1];
  16.    float monto;
  17.    int mes;
  18.    struct registro1* sig;
  19.  
  20. }ingreso;
  21.  
  22. int introduceRegistro(ingreso **pIngreso);//le pasamos el puntero original de la lista
  23.  
  24. //agrega un elemento a la lista
  25. void addIngreso(ingreso **pIngreso , ingreso *aux );
  26.  
  27. //imprime el campo concepto de todos los elementos en la lista
  28. void imprimeConcepto(ingreso *pIngreso);
  29.  
  30.  
  31. int main()
  32. {
  33.    ingreso *pIngreso = NULL;
  34.    printf("\nIngresa los datos del registro \n");
  35.    introduceRegistro(&pIngreso);
  36.  
  37.    printf("presiona una tecla para continuar...\n") ;
  38.    getchar();
  39.    return 0;
  40. }
  41.  
  42. void addIngreso(ingreso **pIngreso , ingreso *aux ){
  43. if(*pIngreso == NULL){
  44. *pIngreso = aux;
  45. }else{
  46. //llamamos recursivamente a la función
  47. addIngreso(&((*pIngreso)->sig) , aux);
  48. }
  49. }
  50.  
  51. void imprimeConcepto(ingreso *pIngreso){
  52. if(pIngreso != NULL){
  53. printf("%s \n", pIngreso->concepto);
  54. imprimeConcepto(pIngreso->sig);
  55. }
  56. }
  57.  
  58. int introduceRegistro(ingreso **pIngreso)
  59. {
  60.    int i;
  61.    //lo usamos para ir agregando la información
  62.    ingreso *aux;
  63.  
  64.    for(i=0 ;  i<MAX_REG ; i++ ){    
  65.        aux = (ingreso*)malloc(sizeof(ingreso));//A todo puntero hay que asignarle memoria.
  66.  
  67.        printf("Concepto :");
  68.        gets(aux->concepto);
  69.  
  70.        printf("RFC :");
  71.        gets(aux->RFC);    
  72.  
  73.        printf("Monto :");
  74.        scanf("%f",&aux->monto);
  75.        LIMPIAR_BUFFER;      
  76.  
  77.        printf("Mes :");
  78.        scanf("%d",&aux->mes);
  79. LIMPIAR_BUFFER;
  80.  
  81.        //lo agregamos a la lista
  82.        addIngreso(pIngreso, aux);
  83.    }
  84.  
  85.    printf("Los valores del campo concepto de la lista de ingresos son : \n");
  86.   //mostramos el "concepto" de todos los campos
  87.   imprimeConcepto(*pIngreso);
  88.  
  89. return 0;
  90. }
  91.  

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
Wiki

Desconectado Desconectado

Mensajes: 3.158


I'Love...!¡.


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

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
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>//funcion malloc()
  4. #include <string.h> // funcion strcpy()
  5.  
  6. #define MAX_REG 20 //Define el maximo numero de registros
  7. #define MAX_CONCEPTO 30+1
  8. #define MAX_RFC 21+1
  9.  
  10.  
  11. // Primero definimos los tipos
  12. typedef struct registro1
  13. {
  14.    char concepto[MAX_CONCEPTO];
  15.    char RFC[MAX_RFC];
  16.    float monto;
  17.    int mes;
  18.    struct registro1* next;
  19.  
  20. }INGRESO,   //  Tipo..
  21. *LPINGRESO; //  Puntero a un Tipo en lugarde esrbir *INGRESO se escribe LPINGRESO
  22.  
  23. LPINGRESO introduceRegistro(LPINGRESO lpIngreso, int* iCount, int iMaxReg, int addIn);//le pasamos el puntero original de la lista
  24. int releaseIngresos(LPINGRESO lpIngreso);
  25. LPINGRESO getLastIngreso(LPINGRESO lpIngreso);
  26.  
  27. int main()
  28. {
  29.    LPINGRESO lpIngreso = NULL;
  30.    printf("\nIngresa los datos del registro \n");
  31.  
  32.    lpIngreso = introduceRegistro(lpIngreso,    //  Empesamos desde este registro... obviamente como es NULL creara un nuevo registro...
  33.                                  NULL,
  34.                                  MAX_REG,
  35.                                  1);
  36.    printf("%d\n", releaseIngresos(lpIngreso));
  37.    getchar();
  38.  
  39.    return EXIT_SUCCESS;
  40. }
  41.  
  42. //  Libera TODOS LOS NODOS siguientes de INGRESO...
  43. int releaseIngresos(LPINGRESO lpIngreso)
  44. {
  45.    int iRet = 0;
  46.  
  47.    if (lpIngreso)
  48.    {
  49.        iRet = 1 + releaseIngresos(lpIngreso->next);    //  Liberamos los hijos...
  50.        free(lpIngreso);                            //  Liberamos...
  51.    }
  52.    return iRet;
  53. }
  54.  
  55. //  Retorna el ultimo registro...
  56. LPINGRESO getLastIngreso(LPINGRESO lpIngreso)
  57. {
  58.    if (lpIngreso)
  59.        while (lpIngreso->next)
  60.            lpIngreso = lpIngreso->next;
  61.    return lpIngreso;
  62. }
  63.  
  64. /// La funci&#243;n va a retornar un LPINGRESO al 1er elemento INGRESO...
  65. LPINGRESO introduceRegistro(LPINGRESO lpIngreso,    //  Lista desde donde se empesara a crear...
  66.                            int* iCount,            //  Ouput Retorna la cantidad de registros creados...
  67.                            int iMaxReg,            //  MAXIMO de registros a crear...
  68.                            int addIn)              //  Si lpIngreso->next apunta a otro registro, los registros a crear se deben insertarse:
  69.                                                    //  -1 Creamos lo registros entre lpIngreso y lpIngreso->next...
  70.                                                    //  0 Eliminar TODOS apartir de lpIngreso->next e insertar los nuevos.
  71.                                                    //  1 Inserta los registros al final al final de la lista.
  72.                                                    //  Se ignora este parametro si lpIngreso es NULL.
  73. {
  74.    int i = 0;
  75.    LPINGRESO lpNewIngreso = NULL;
  76.    LPINGRESO lpNextStaticIngreso = NULL;
  77.    LPINGRESO lpFirtsIngreso = lpIngreso;
  78.  
  79.    /// Si lpIngreso ya tiene otros registros enlazados podemos hacer tres cosas
  80.    if (lpIngreso)
  81.        switch(addIn)
  82.        {
  83.            case -1:    //  Agregamos los nuevos seguido a lpIngreso pero antes de lpIngreso->next
  84.                lpNextStaticIngreso = lpIngreso->next;
  85.                break;
  86.  
  87.            case 0:     //  Eliminamos TODOs lo registros desde lpIngreso->next...
  88.                releaseIngresos(lpIngreso->next);
  89.                break;
  90.  
  91.            default:    //  Buscamos el ultimo de la lista y empesamos a agregarlos apartir de este.
  92.                lpIngreso = getLastIngreso(lpIngreso);
  93.                break;
  94.        }
  95.  
  96.    for(i = 0
  97.        //, lpIngreso->next == NULL ->> No tiene caso comprobar con NULL... creo que querias asignarle NULL, &#191;no?.
  98.        ;i < iMaxReg;  //  Cantidad de registros...
  99.        i++)           //  Contador creciente en 1.
  100.    {
  101.        lpNewIngreso = (LPINGRESO)malloc(sizeof(INGRESO));
  102.  
  103.        if (!lpNewIngreso)  //  Se reservo la memoria deseada?...
  104.            break;  //  Salimos del for()...
  105.  
  106.        memset(lpNewIngreso, 0, sizeof(INGRESO));   //  Limpiamos el bloque de memoria...
  107.  
  108.        if (!lpFirtsIngreso)
  109.            lpFirtsIngreso = lpNewIngreso;
  110.  
  111.        //  Enlazamos con el anterior...
  112.        if (lpIngreso)
  113.            lpIngreso->next = lpNewIngreso;
  114.  
  115.        lpIngreso = lpNewIngreso;
  116.  
  117.        /// El llenado de datos se puede hacer despues de haber creado los elementos...
  118.        /*
  119.         fprintf(stdout, "Concepto:\n");
  120.         fgets(lpIngreso->concepto, MAX_CONCEPTO - 1, stdin);    //  Hay que leer solo la longitud requerida...
  121.  
  122.         fprintf(stdout, "RFC:\n");
  123.         fgets(lpIngreso->concepto, MAX_RFC - 1, stdin);    //  Hay que leer solo la longitud requerida...
  124.  
  125.         fprintf(stdout, "Monto:\n");
  126.         scanf("%f", &lpIngreso->monto);
  127.  
  128.         fprintf(stdout, "Mes:\n");
  129.         scanf("%d", &lpIngreso->mes);
  130.         */
  131.    }
  132.  
  133.    if (iCount)
  134.        (*iCount) = i;
  135.  
  136.    lpIngreso->next = lpNextStaticIngreso;
  137.  
  138.    return lpFirtsIngreso;
  139. }
  140.  
  141.  

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

The Dark Shadow is my passion.
m@o_614


Desconectado Desconectado

Mensajes: 389


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

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

Xandrete

Desconectado Desconectado

Mensajes: 210



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

¡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
  1. #include <iostream>
  2. #include <string>
  3. #define  MAX_REG 20
  4. using namespace std;
  5.  
  6. struct Ingreso {
  7. string concepto;
  8. string RFC;
  9. float monto;
  10. int mes;
  11. Ingreso* sig;
  12.  
  13. };
  14.  
  15. void rellenarDatos(Ingreso* ing) {
  16. cout << "Concepto: ";
  17. cin >> ing->concepto;
  18. cout << "RFC: ";
  19. cin >> ing->RFC;
  20. cout << "Monto: ";
  21. cin >> ing->monto;
  22. cout << "Mes: ";
  23. cin >> ing->mes;
  24. }
  25.  
  26. Ingreso* agregarIngreso(Ingreso* ultimoIngreso) {
  27. Ingreso* siguienteIngreso;
  28. if (ultimoIngreso == NULL) siguienteIngreso = new Ingreso;
  29. else siguienteIngreso = ultimoIngreso->sig = new Ingreso;
  30. rellenarDatos(siguienteIngreso);
  31. return siguienteIngreso;
  32. }
  33.  
  34. Ingreso* introduceRegistro() {
  35. int i;
  36. Ingreso* pIngreso;
  37. Ingreso* ultimoIngreso;
  38. pIngreso = ultimoIngreso = agregarIngreso(NULL);
  39. for(i=1;i<MAX_REG;++i)
  40. ultimoIngreso = agregarIngreso(ultimoIngreso);
  41. ultimoIngreso->sig = NULL;
  42. return pIngreso;
  43. }
  44.  
  45. int main() {
  46. cout << "Ingresa los datos del registro" << endl;
  47. Ingreso* pIngreso = introduceRegistro();
  48. /* ... */
  49. }

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
Programación Visual Basic
bautistasbr 4 2,097 Último mensaje 30 Septiembre 2005, 19:35 pm
por NYlOn
Problemas con punteros en listas.
Programación C/C++
samur88 6 5,876 Último mensaje 10 Enero 2011, 00:09 am
por samur88
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines