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

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problemas con mostrar un registro
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problemas con mostrar un registro  (Leído 3,042 veces)
Sword9K

Desconectado Desconectado

Mensajes: 10


Ver Perfil
Problemas con mostrar un registro
« en: 9 Abril 2020, 23:18 pm »

Hola, es sobre un problema que estoy teniendo a la hora de mostrar unos datos con punteros, lo que pasa es que uno de los datos que ingreso se "cambia" por un carácter especial o algo así.

Aquí esta parte del código, perdón si esta asi, lo copie rápido.

Código
  1. #include <string.h>
  2. #include <iostream>
  3. #include <windows.h>
  4. #include <conio.h>
  5.  
  6. using namespace std;
  7.  
  8. void gt(int x, int y){             // -Posicion X y Y en el Programa
  9. HANDLE Manipulador;  //Puntero
  10. COORD Coordenadas; //Coordenadas
  11. Manipulador = GetStdHandle(STD_OUTPUT_HANDLE); //Contenedor del Programa
  12. Coordenadas.X = x; //Posicion en X
  13. Coordenadas.Y = y; //Posicion en Y
  14. SetConsoleCursorPosition(Manipulador,Coordenadas); //Envia el Contenedor y variable para la posicion
  15. }
  16.  
  17. void formu(){
  18. system("cls");
  19. gt(15,9); cout<<"Codigo: ";
  20. gt(15,11); cout<<"Nombres: ";
  21. gt(15,12); cout<<"Apellidos: ";
  22. gt(15,14); cout<<"Nota 1: ";
  23. gt(15,15); cout<<"Nota 2: ";
  24. gt(15,17); cout<<"Su Nota Definitiva es: ";
  25. }
  26.  
  27. struct notas{
  28. char nom[50];
  29. char apel[50];
  30. char cod[50];
  31. float n1, n2;
  32. float defi;
  33. }alu, *pun=&alu;
  34.  
  35. void capt();
  36. void list();
  37. void consul();
  38. int ne;
  39.  
  40. int main(){
  41. char op;
  42. do{
  43. system("cls");
  44. gt(20,10); cout<<"MENU REGISTROS";
  45. gt(22,12); cout<<"1. Capturar.";
  46. gt(22,13); cout<<"2. Consultar registros.";
  47. gt(22,14); cout<<"3. Salir.";
  48.  
  49. gt(23,16); cout<<char(167)<<"Digite un numero: "; op = getch();
  50.  
  51. switch(op){
  52. case '1':
  53. capt();
  54. break;
  55. case '2':
  56. consul();
  57. break;
  58. case '3':
  59. gt(6,18); cout<<"Saliendo...";
  60. Sleep(200);
  61. gt(5,25); exit(1);
  62. break;
  63. default:
  64. gt(6,18); cout<<"Debe digitar un numero del 1 al 3...";
  65. system("pause");
  66. break;
  67. }
  68. }
  69. while(op != '3');
  70. }
  71.  
  72. void capt(){
  73. system("cls");
  74. gt(15,10); cout<<"Digite el Numero de Formularios a agregar: "; cin>>ne;
  75. const int ju = ne;
  76.  
  77. for(int i=0;i<ju;i++){
  78. formu();
  79. fflush(stdin);
  80. gt(23,9); gets((pun+i)->cod);
  81. gt(24,11); gets((pun+i)->nom);
  82. gt(26,12); gets((pun+i)->apel);
  83. gt(23,14); cin>>(pun+i)->n1;
  84. gt(23,15); cin>>(pun+i)->n2;
  85.  
  86. (pun+i)->defi=((pun+i)->n1+(pun+i)->n2)/2;
  87. gt(38,17); cout<<(pun+i)->defi;
  88. system("pause");
  89. }
  90. ne = ju;
  91. }
  92.  
  93. void consul(){
  94. char op;
  95. do{
  96. system("cls");
  97. gt(20,10); cout<<"MENU - Consultas";
  98. gt(22,12); cout<<"1. Listar.";
  99. gt(22,13); cout<<"2. Volver al menu anterior";
  100. gt(22,14); cout<<"3. Salir";
  101.  
  102. gt(23,16); cout<<"Digite un numero: "; op = getch();
  103.  
  104. switch(op){
  105. case '1':
  106. list();
  107. break;
  108. case '2':
  109. gt(6,18); cout<<"Volviendo...";
  110. Sleep(200);
  111. main();
  112. break;
  113. case '3':
  114. gt(6,18); cout<<"Saliendo...";
  115. Sleep(200);
  116. gt(5,25); exit(1);
  117. break;
  118. default:
  119. gt(6,18); cout<<"Digite un numero del 1 al 3...";
  120. system("pause");
  121. break;
  122. }
  123. }
  124. while(op != '4' || op == '2');
  125. system("pause");
  126. }
  127.  
  128. void list(){
  129. system("cls");
  130. fflush(stdin);
  131. if((pun)->defi == 0){
  132. gt(15, 10); cout<<"No se Encontraron Registros...";
  133. }
  134. else{
  135. gt(16,8); cout<<"--- REGISTROS ---";
  136.  
  137. gt(3,10); cout<<"No.";
  138. gt(7,10); cout<<"Codigo";
  139. gt(17,10); cout<<"Nombre";
  140. gt(33,10); cout<<"Apellido";
  141. gt(47,10); cout<<"Nota 1";
  142. gt(57,10); cout<<"Nota 2";
  143. gt(67,10); cout<<"Definitiva";
  144.  
  145. for(int i=0;i<ne;i++){
  146. gt(3,i+12); cout<<i+1;
  147. gt(7,i+12); cout<<(pun+i)->cod;
  148. gt(17,i+12); cout<<(pun+i)->nom;
  149. gt(32,i+12); cout<<(pun+i)->apel;
  150. gt(47,i+12); cout<<(pun+i)->n1;
  151. gt(57,i+12); cout<<(pun+i)->n2;
  152. gt(67,i+12); cout<<(pun+i)->defi;
  153. }
  154. system("pause");
  155. }
  156. }
  157.  

Y asi me queda cuando quiero mostrar los registros.

                --- REGISTROS ---

   No. Codigo    Nombre          Apellido      Nota 1    Nota 2    Definitiva

   1   32GRE     ANDRES         SUR            45        20        32.5
   2   AH3H2     ♥              PEREZ          34        50        42
   3   4H2BG     ESTEBAN        HONZ           45        35        40Presione una tecla para continuar . . .


En línea

ThunderCls


Desconectado Desconectado

Mensajes: 455


Coder | Reverser | Gamer


Ver Perfil WWW
Re: Problemas con mostrar un registro
« Respuesta #1 en: 10 Abril 2020, 04:32 am »

Tu declaracion de "pun" es la siguiente:

Código
  1. struct notas{
  2. char nom[50];
  3. char apel[50];
  4. char cod[50];
  5. float n1, n2;
  6. float defi;
  7. }alu, *pun=&alu;

Significa que "pun" es simplemente un puntero a una variable de tipo estructura "notas". Luego mas adelante haces algo como:

Código
  1. (pun+i)->cod

Significa que estas accediendo a una posicion en memoria de la que no tienes control (intentas acceder mas alla de los limites de tu variable con pun+i). Cuando accedes a una zona de memoria no reservada, el contenido es incierto ya que tu aplicacion o cualquier otra puede usarla. Una posible solucion es declarar "pun" como un array de estructuras, o mejor aun, como un contenedor dinamico (vector, list).

He modificado solamente la declaracion y uso de la variable "pun" para que tengas una idea:

Código
  1. #include <string.h>
  2. #include <iostream>
  3. #include <windows.h>
  4. #include <conio.h>
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. void gt(int x, int y) {             // -Posicion X y Y en el Programa
  10. HANDLE Manipulador;  //Puntero
  11. COORD Coordenadas; //Coordenadas
  12. Manipulador = GetStdHandle(STD_OUTPUT_HANDLE); //Contenedor del Programa
  13. Coordenadas.X = x; //Posicion en X
  14. Coordenadas.Y = y; //Posicion en Y
  15. SetConsoleCursorPosition(Manipulador, Coordenadas); //Envia el Contenedor y variable para la posicion
  16. }
  17.  
  18. void formu() {
  19. system("cls");
  20. gt(15, 9); cout << "Codigo: ";
  21. gt(15, 11); cout << "Nombres: ";
  22. gt(15, 12); cout << "Apellidos: ";
  23. gt(15, 14); cout << "Nota 1: ";
  24. gt(15, 15); cout << "Nota 2: ";
  25. gt(15, 17); cout << "Su Nota Definitiva es: ";
  26. }
  27.  
  28. struct notas {
  29. char nom[50];
  30. char apel[50];
  31. char cod[50];
  32. float n1, n2;
  33. float defi;
  34. }alu;
  35. vector<notas> pun;
  36.  
  37. void capt();
  38. void list();
  39. void consul();
  40. int ne;
  41.  
  42. int main() {
  43. char op;
  44. do {
  45. system("cls");
  46. gt(20, 10); cout << "MENU REGISTROS";
  47. gt(22, 12); cout << "1. Capturar.";
  48. gt(22, 13); cout << "2. Consultar registros.";
  49. gt(22, 14); cout << "3. Salir.";
  50.  
  51. gt(23, 16); cout << char(167) << "Digite un numero: "; op = _getch();
  52.  
  53. switch (op) {
  54. case '1':
  55. capt();
  56. break;
  57. case '2':
  58. consul();
  59. break;
  60. case '3':
  61. gt(6, 18); cout << "Saliendo...";
  62. Sleep(200);
  63. gt(5, 25); exit(1);
  64. break;
  65. default:
  66. gt(6, 18); cout << "Debe digitar un numero del 1 al 3...";
  67. system("pause");
  68. break;
  69. }
  70. } while (op != '3');
  71. }
  72.  
  73. void capt() {
  74. system("cls");
  75. gt(15, 10); cout << "Digite el Numero de Formularios a agregar: "; cin >> ne;
  76. const int ju = ne;
  77.  
  78. for (int i = 0; i < ju; i++) {
  79. struct notas nota;
  80. formu();
  81. fflush(stdin);
  82. gt(23, 9); cin >> nota.cod;
  83. gt(24, 11); cin >> nota.nom;
  84. gt(26, 12); cin >> nota.apel;
  85. gt(23, 14); cin >> nota.n1;
  86. gt(23, 15); cin >> nota.n2;
  87.  
  88. nota.defi = (nota.n1 + nota.n2) / 2;
  89. gt(38, 17); cout << nota.defi;
  90. pun.push_back(nota);
  91. system("pause");
  92. }
  93. ne = ju;
  94. }
  95.  
  96. void consul() {
  97. char op;
  98. do {
  99. system("cls");
  100. gt(20, 10); cout << "MENU - Consultas";
  101. gt(22, 12); cout << "1. Listar.";
  102. gt(22, 13); cout << "2. Volver al menu anterior";
  103. gt(22, 14); cout << "3. Salir";
  104.  
  105. gt(23, 16); cout << "Digite un numero: "; op = _getch();
  106.  
  107. switch (op) {
  108. case '1':
  109. list();
  110. break;
  111. case '2':
  112. gt(6, 18); cout << "Volviendo...";
  113. Sleep(200);
  114. main();
  115. break;
  116. case '3':
  117. gt(6, 18); cout << "Saliendo...";
  118. Sleep(200);
  119. gt(5, 25); exit(1);
  120. break;
  121. default:
  122. gt(6, 18); cout << "Digite un numero del 1 al 3...";
  123. system("pause");
  124. break;
  125. }
  126. } while (op != '4' || op == '2');
  127. system("pause");
  128. }
  129.  
  130. void list() {
  131. system("cls");
  132. fflush(stdin);
  133. if (pun.empty()) {
  134. gt(15, 10); cout << "No se Encontraron Registros...";
  135. }
  136. else {
  137. gt(16, 8); cout << "--- REGISTROS ---";
  138.  
  139. gt(3, 10); cout << "No.";
  140. gt(7, 10); cout << "Codigo";
  141. gt(17, 10); cout << "Nombre";
  142. gt(33, 10); cout << "Apellido";
  143. gt(47, 10); cout << "Nota 1";
  144. gt(57, 10); cout << "Nota 2";
  145. gt(67, 10); cout << "Definitiva";
  146.  
  147. for (int i = 0; i < ne; i++) {
  148. auto nota = pun.at(i);
  149. gt(3, i + 12); cout << i + 1;
  150. gt(7, i + 12); cout << nota.cod;
  151. gt(17, i + 12); cout << nota.nom;
  152. gt(32, i + 12); cout << nota.apel;
  153. gt(47, i + 12); cout << nota.n1;
  154. gt(57, i + 12); cout << nota.n2;
  155. gt(67, i + 12); cout << nota.defi;
  156. }
  157. system("pause");
  158. }
  159. }

Saludos


En línea

-[ "…I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/
Sword9K

Desconectado Desconectado

Mensajes: 10


Ver Perfil
Re: Problemas con mostrar un registro
« Respuesta #2 en: 10 Abril 2020, 14:16 pm »

Gracias.

Ya pude entender mejor donde estaba el problema de los punteros, voy a intentar hacerlo con un array de estructuras, no entiendo muy bien la libreria vector xD.

Lo del problema es que, como el puntero accedia a un memoria que no tenia reservada, me cambiaba algunas variables, por ejemplo.

Código
  1. void capt(){
  2. system("cls");
  3. gt(15,10); cout<<"Digite el Numero de Formularios a agregar: "; cin>>ne;
  4. const int ju = ne;
  5.  
  6. for(int i=0;i<ju;i++){
  7. formu();
  8. fflush(stdin);
  9. gt(23,9); gets((pun+i)->cod);
  10. gt(24,11); gets((pun+i)->nom);
  11. gt(26,12); gets((pun+i)->apel);
  12. gt(23,14); cin>>(pun+i)->n1;
  13. gt(23,15); cin>>(pun+i)->n2;
  14.  
  15. (pun+i)->defi=((pun+i)->n1+(pun+i)->n2)/2;
  16. gt(38,17); cout<<(pun+i)->defi;
  17. system("pause");
  18. }
  19. ne = ju;
  20. }
  21.  

Con ne, la variable para pedir el numero de formularios para el for, como que cambiaba su valor y no salia del for, por eso agregue una constante "const int ju", digamos para solucionarlo y que su valor no cambiara, pero aun asi tambien cambiaba los demas valores.

Ya lo unico que me no entiendo es,  si pongo un numero cualquiera en el for, ya me salen los datos bien. Como ejemplo, pongo que solo se hagan 3 formularios, y eso ya arregla el problema.

Código
  1. void capt(){
  2. system("cls");
  3.  
  4. for(int i=0;i<3;i++){
  5. formu();
  6. fflush(stdin);
  7. gt(23,9); gets((pun+i)->cod);
  8. gt(24,11); gets((pun+i)->nom);
  9. gt(26,12); gets((pun+i)->apel);
  10. gt(23,14); cin>>(pun+i)->n1;
  11. gt(23,15); cin>>(pun+i)->n2;
  12.  
  13. (pun+i)->defi=((pun+i)->n1+(pun+i)->n2)/2;
  14. gt(38,17); cout<<(pun+i)->defi;
  15. system("pause");
  16. }
  17. }
  18.  
En línea

RayR

Desconectado Desconectado

Mensajes: 239


Ver Perfil
Re: Problemas con mostrar un registro
« Respuesta #3 en: 10 Abril 2020, 19:15 pm »

Primero, algunas sugerencias/correciones. fflush(stdin) es incorrecto. La función fflush sólo se debe usar para flujos de salida, como stdout. Hacerlo con stdin es una violación a las reglas del propio lenguaje y aunque te pueda funcionar en Windows (en los otros sistemas operativos falla), no hay garantía de que siempre lo haga. En C++, una forma de limpiar el buffer es:
Código
  1. #include <limits>
  2. ...
  3. cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  4.  
O al estilo C, con while y getchar. Son básicamente las únicas maneras correctas de hacerlo. A veces recomiendan una con fseek, pero es tan incorrecta como fflush(stdin).
También deberías evitar gets. Es una función insegura y que desde hace años ya no es parte oficial de C o C++, y algunos compiladores incluso te darán error. En su lugar usa getline, cin.getline, o fgets.

En cuanto a tu problema, como ya te comentaron, es un error acceder a memoria que no reservaste. pun+1, pun+2, etc. apuntan a direcciones de memoria que no deberías tocar. Lo que sucede cuando lo haces es que estás escribiendo a direcciones que podrían estar ocupadas por otras variables (o que otras variables van a ocupar más adelante en la ejecución de tu programa), e incluso puedes ocasionar que tu programa se cierre inesperadamente, al estar accediendo a memoria que el sistema operativo no reservó para tu programa.

En tu caso, por lo que comentas, lo que debe estar pasando es que ptr+1 se refiere a la dirección de memoria ocupada por ne. Por lo tanto, cuando modificas ne, a la vez estás modificando un campo de ptr+1, y viceversa. Al usar la variable ju, evitas que tus gets modifiquen indirectamente a ne, pero al final de esa función, en la línea: ne = ju; al modificar ne, indirectamente estás modificando un campo de ptr+1, y de ahí los símbolos que mencionas. Por cierto, ju ni siquiera necesitaba ser const. Al ser variable local de capt, se encontrará en una posición de la memoria algo alejada de alu, que es variable global, por lo que no se superponen. Además, el calificador const sólo impide que en tu código manualmente modifiques la variable, pero todavía se puede modificar indirectamente si tienes un puntero a su dirección. De cualquier forma, el problema es que jamás debes acceder a memoria que no hayas reservado. Aunque algunas veces un programa que lo haga parezca funcionar correctamente, nunca es así. Internamente modifica algo que no debería y eventualmente causará problemas.
En línea

Sword9K

Desconectado Desconectado

Mensajes: 10


Ver Perfil
Re: Problemas con mostrar un registro
« Respuesta #4 en: 11 Abril 2020, 04:24 am »

gracias, ya he podido arreglar el programa. Sobre el problema, lo hice con el depurador y vi que, al poner un numero en el for, al menos el ciclo si terminaba, si utilizaba ne, después de usar pun+i, cambiaba el valor de ne y no terminaba, o cambiaba el valor de los string.

En el programa deje solo un puntero en el struct.

Código
  1. struct notas{
  2.  
  3. ...
  4.  
  5. }*pun;
  6.  

y luego en la funcion capt(), puse un arreglo dinamico.

Código
  1. void capt(){
  2. system("pause");
  3. gt(15,10); cout<<"Digite el Numero de Formularios a agregar: "; cin>>ne;
  4.  
  5. pun = new notas [ne];
  6.  
  7. for(int i=0;i<ne;i++){
  8. ...
  9. }
  10.  

Ademas, cambie el fflush() con el cin.ignore() y utilice el cin.getline() con los punteros.
« Última modificación: 11 Abril 2020, 04:32 am por Sword9K » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
mostrar los valores de una key del registro de windows
Programación C/C++
andres_89a 3 2,895 Último mensaje 1 Octubre 2012, 18:05 pm
por Eternal Idol
mostrar registro de tabla
PHP
basickdagger 5 2,475 Último mensaje 26 Febrero 2013, 18:26 pm
por basickdagger
Mostrar registro de una acción
Java
siuxoes 1 1,444 Último mensaje 1 Diciembre 2013, 19:48 pm
por Zoik
¿Cómo mostrar en la web un registro formateado de una BBDD?
Scripting
joanballester 1 1,822 Último mensaje 17 Diciembre 2015, 12:40 pm
por ivancea96
Mostrar un registro asociado a otro??
Bases de Datos
Geg1 2 2,630 Último mensaje 17 Marzo 2018, 19:45 pm
por srWhiteSkull
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines