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


Tema destacado: Introducción a Git (Primera Parte)


  Mostrar Mensajes
Páginas: 1 ... 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [34] 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 ... 102
331  Programación / Programación C/C++ / Re: Process returned -1073741819 en: 31 Mayo 2020, 16:13 pm
Otras cosa que veo es en la línea 241, con ese n-1 estás dejando la última posición sin "limpiar".
Seguramente tengas algún problema en la llamada recursiva de tipus3d() (línea 407).

Lo mejor que puedes hacer es usar algún depurador o hacerlo a la vieja ausanza con unos printf() por ahí para ver cómo van cambiando las variables.
332  Programación / Programación C/C++ / Re: Process returned -1073741819 en: 31 Mayo 2020, 15:47 pm
Lo que veo a simple vista es que el array vmin tiene una longitud de n que no sé cuánto será puesto que depende del fichero pero en la función tipus3d() le asignas 100 veces el valor 0 a vmin[100].

Mira a ver si corrigiendo eso, el error se arregla. No he mirado mucho más puesto que el código es muy grande y hay que decir que la identación no ayuda mucho a identificar los bloques de código. :rolleyes:

Suerte. :-X

PD: Para pasar un puntero a una función, en vez de usar &(*p), puedes usar directamente p. Los operadores & y * se anulan al final.
333  Programación / Bases de Datos / Re: Pasar modelo entidad relacion a MySQL en: 31 Mayo 2020, 11:23 am
Entre las demás tablas y relaciones, habría que crearlas normal o como has hecho tú?
No sé a qué te refieres con crearlas normal o como las he hecho yo...

Si te refieres a lo de crear una nueva tabla para la relación, eso es necesario únicamente para las relaciones con cardinalidad N:M. Digamos que la regla general es:
  • Cardinalidad N:M -> Nueva tabla formada por las PKs de las dos tablas [+ discriminantes] como PK de la nueva, otros atributos de la relación y FKs de cada PK original a su tabla de origen.
  • Cardinalidad 1:N -> La tabla con cardinalidad N contiene una FK a la PK de la tabla con cardinalidad 1.
  • Cardinalidad 1:1 -> Una tabla contiene la FK a la PK de la otra. Cuál? Depende del problema muchas veces. La que más información aporte.

Si te refieres al ON DELETE CASCADE, pues dependerá de lo que quieras eliminar en cascada o no.
334  Programación / Bases de Datos / Re: Pasar modelo entidad relacion a MySQL en: 31 Mayo 2020, 09:25 am
Así es, una relación de cardinalidad N:M constituye una nueva entidad (tabla) que estará formada por las claves primarias de ambas tablas originales (que formarán conjuntamente la clave primaria de la nueva tabla) y los atributos de relación que pudiese haber (pudiendo ser alguno de ellos un discrimante y entonces habría que incluirlo en la clave primaria de la nueva tabla).

Código
  1. CREATE TABLE [IF NOT EXISTS] Pedido (
  2.  id_pedido INT PRIMARY KEY [AUTO_INCREMENT],
  3.  ...
  4. );
  5.  
  6. CREATE TABLE [IF NOT EXISTS] Producto (
  7.  id_producto INT PRIMARY KEY [AUTO_INCREMENT],
  8.  ...
  9. );
  10.  
  11. -- Tabla resultante de la relacion:
  12. CREATE TABLE [IF NOT EXISTS] Inventario (
  13.  id_pedido INT,
  14.  id_producto INT,
  15.  cantidad INT [DEFAULT 1], -- Cantidad del producto id_producto que hay en el pedido id_pedido, [por defecto: 1]
  16.  PRIMARY KEY(id_pedido, id_producto),
  17.  [CONSTRAINT FK_Inventario_Pedido] FOREIGN KEY (id_pedido) REFERENCES Pedido(id_pedido),
  18.  [CONSTRAINT FK_Inventario_Producto] FOREIGN KEY (id_producto) REFERENCES Producto(id_producto)
  19. );
Por ejemplo a esta relación le vendría bastante bien el atributo de relación <cantidad> para saber cuántos productos de cada tipo hay en cada pedido.
Las partes entre corchetes [] son opcionales y si se ponen tienes que quitar los corchetes.


El DELETE ON CASCADE tienes que incluirlo en la FOREIGN KEY de la tabla que quieres que se elimine en cascada, es decir, de la tabla opuesta a la que tú vas a borrar. En este caso si quieres que al eliminar un Pedido, se elimine un Pago, Pedido tiene que ser la tabla independiente (que no contiene la FK) y Pago será la dependiente.
Código
  1. CREATE TABLE [IF NOT EXISTS] Pago (
  2.  id_pago INT PRIMARY KEY [AUTO_INCREMENT],
  3.  ...
  4.  id_pedido INT,
  5.  [CONSTRAINT FK_Pago_Pedido] FOREIGN KEY (id_pedido) REFERENCES Pedido(id_pedido) ON DELETE CASCADE
  6. );
335  Programación / Programación General / Re: ¿Con qué clase de programación te sientes más identificado? en: 30 Mayo 2020, 21:07 pm
Yo diría que me siento más identificado con la programación de bajo nivel o nivel medio. Empecé con una mezcla de C y C++ hasta que aprendí a diferenciarlos (algo que parece muy tonto pero mucha gente los usa indiferentemente) y aunque he probado algún lenguaje más, estos siguen ahí presentes.
Me gusta saber cómo funcionan las cosas y los lenguajes de menor nivel de abstracción te permiten entender mejor el funcionamiento directo con memoria. Hay que decir que ahora tengo que trabajar con Java y echo de menos mis queridos punteros (aunque mucha gente los odia) y otras tantas cosas que se podían hacer en C/C++ y que Java no permite.

Además pasar de bajo nivel a alto nivel es más sencillo que a la inversa. Alguien que sabe trabajar con memoria puede olvidarse de ella y dejarse llevar pero alguien que no tiene ni idea de cómo funciona la memoria tiene más problemas para empezar a trabajar con ella.

Lo cierto es que de la enorme lista de lenguajes que hay en la encuesta, aunque he oído sobre muchos de ellos, he probado muy poquitos. Me da pereza eso de cambiar de lenguaje cada poco tiempo (y cada mucho también :xD). Coger un lenguaje, aprender la sintaxis básica y cuando empiezas a hacer proyectos complejos, coges y empiezas a probar otro... Se vuelve un poco repetitivo, a mi parecer. Te limitas a hacer siempre unas entradas/salidas de datos estándar y unos algoritmos básicos.

Tengo pensado probar algunos más pero seguramente en los que más me especialice sean C++, Java y algún otro que vaya descubriendo del estilo.

PD: Por si no se ha notado por la ausencia de mención: no me llama la atención la programación Web. Respeto a los que les guste obviamente y seguro que si me meto con ello le acabaría cogiendo el gustillo pero de momento es algo que no me llama.
336  Programación / Programación C/C++ / Re: estructuras y lectura de archivos en C en: 30 Mayo 2020, 11:30 am
El problema principal es la separación que estás haciendo en tokens o partes.
Buscas hasta la primera coma (,) para localizar el nombre del libro pero de seguido guardas el nombre del autor también sin haber buscado hasta la siguiente coma. Por lo tanto, el nombre del libro y el autor siempre son la misma cadena.
A partir de ahí ya se descuadran todos los cálculos (que tampoco entiendo esos fgets() con longitud 4 y 5...) y se guarda todo mal.

Además otro problema es que la cadena que usas para guardar cada línea del fichero temporalmente tiene una longitud de 50 y hay líneas que superan ese número de caracteres por lo que los caracteres que no entran en una línea, se leen en la siguiente.

Otro otro tema importante cuando se trabaja con memoria dinámica es que esa memoria tienes que liberarla manualmente usando free().

Y otro tema es usar return para salir en caso de error. En la función main() se puede hacer porque de un return acaba el programa pero en otras funciones auxiliares, llamar a return lo que hace es devolver el control a la función que llamó a esta. Es más correcto utilizar exit().
Además el valor 0 se suele asociar a que todo ha finalizado correctamente. Para errores es mejor usar -1. En conjunto: exit(-1).

Otros consejos son:
  • Utilizar una constante para la longitud de la cadena que te permita modificarlo rápidamente sin tener que ir mirando por todo el código.
  • No utilizar variables globales, como en tu caso el puntero l.
  • Para separar una cadena en base a un patrón o varios tienes la función strtok().
  • Para "vaciar" una cadena no es necesario poner '\0' a todas sus posiciones. Basta con hacerlo en la posición 0.

Te dejo otra forma de hacerlo con las modificaciones antes mencionadas:
Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define SIZE 100
  6.  
  7. typedef struct {
  8. char *nombre;
  9. char *autor;
  10. int cantidad;
  11. int precio;
  12. } Libro;
  13.  
  14.  
  15. void liberarMemoria(Libro *libros, int numeroLibros){
  16. for(int i = 0; i < numeroLibros; ++i){
  17. free(libros[i].nombre);
  18. free(libros[i].autor);
  19. }
  20. free(libros);
  21. }
  22.  
  23. void guardarLibro(Libro *libros, char *temporal, int numeroLibros){
  24. char *token = strtok(temporal, ",");
  25. libros[numeroLibros-1].nombre = (char*)malloc((strlen(token)+1) * sizeof(char));
  26. strcpy(libros[numeroLibros-1].nombre, token);
  27.  
  28. token = strtok(NULL, ",");
  29. libros[numeroLibros-1].autor = (char*)malloc((strlen(token)+1) * sizeof(char));
  30. strcpy(libros[numeroLibros-1].autor, token);
  31.  
  32. token = strtok(NULL, ",");
  33. libros[numeroLibros-1].cantidad = atoi(token);
  34.  
  35. token = strtok(NULL, ",");
  36. libros[numeroLibros-1].precio = atoi(token);
  37. }
  38.  
  39. void mostrarLibros(Libro *libros, int numeroLibros){
  40. for(int i = 0; i < numeroLibros; ++i){
  41. printf("***** INFORMACION LIBRO %d *****\n", i+1);
  42. printf("Nombre: %s\n", libros[i].nombre);
  43. printf("Autor: %s\n", libros[i].autor);
  44. printf("Cantidad: %d\n", libros[i].cantidad);
  45. printf("Precio: %d\n", libros[i].precio);
  46. printf("\n");
  47. }
  48. }
  49.  
  50. int main(){
  51. Libro *libros = NULL;
  52. char temporal[SIZE];
  53. FILE *fichero = fopen("libros.txt", "r");
  54.  
  55. int numeroLibros = 0;
  56. while(fgets(temporal, SIZE, fichero)) {
  57. ++numeroLibros;
  58. libros = (Libro*)realloc(libros, numeroLibros * sizeof(Libro));
  59. guardarLibro(libros, temporal, numeroLibros);
  60. }
  61.  
  62. mostrarLibros(libros, numeroLibros);
  63.  
  64. liberarMemoria(libros, numeroLibros);
  65. return 0;
  66. }

PD: Cuando vayas a insertar código utiliza etiquetas de Código GeSHi y selecciona el lenguaje que corresponda a tu código. En tu mensaje anterior ya te las he incluido yo pero para otra ocasión.

PD 2: Aunque no es relevante, el menú que tienes no funciona. Si vas a pedir una opción tendrás que devolverla con un return.
337  Programación / Programación C/C++ / Re: no se como hacer que funcione archivo de encabezado en C++ en: 29 Mayo 2020, 18:55 pm
Nunca he trabajado con Visual Studio pero prueba las siguientes cosas:
  • Escribe la cabecera con comillas dobles:
Código
  1. #include "LibroCalificaciones.h"

  • Comprueba que el nombre del fichero de cabecera concuerda con lo que estás escribiendo, incluso la extensión.
  • Comprueba la ruta del fichero. Tiene que estar en el mismo directorio que el cpp al que lo estás importando. Si está en otro directorio tienes que especificarlo o asegurarte que el compilador está buscando en ese directorio.

No sé si te haya pasado más veces o tengas otros proyectos en los que se importe correctamente. Si es así comprueba qué cosas estás haciendo de manera diferente y puede que ahí esté el fallo.

Cualquier resultado, comenta cómo te ha ido.
Suerte. :-X
338  Programación / Bases de Datos / Re: Trigger SQL en: 29 Mayo 2020, 16:56 pm
Ya lo tengo, al final me ha quedado así, no entiendo muy bien el por qué del  DELIMITER $$ etc pero nos lo exigen así.
En MySQL es obligatorio que cada sentencia termine con punto y coma a diferencia de SQL Server por ejemplo. Si un trigger tiene varias instrucciones, cada una tiene que terminar en punto y coma. Entonces para delimitar el trigger completo tienes que usar un delimitador diferente de ahí el DELIMITER $$.

En estos casos como el trigger solo tiene una instrucción, puedes obviar el BEGIN...END y así no necesitas usar DELIMITER. Pero para otros casos en los que tus triggers tengan más de una instrucción, estarás obligado a utilizarlo.

PD: Utiliza las etiquetas de Código GeSHi para mostrar código. En tu caso selecciona la correspondiente a SQL.
339  Programación / Bases de Datos / Re: Trigger SQL en: 29 Mayo 2020, 16:09 pm
Hola, gracias por responder, voy a probar y te comento.
El segundo según lo que me comentas sería sustituir new por old, y también habría que sustituir Insert on por delete on?
Y en el tercero al igual que en el segundo habría que sustituir algún valor más?
Claro, exactamente. En el segundo caso sería AFTER DELETE ON.

Y en el tercer caso sustituir el INSERT/DELETE por UPDATE. Es más, te diría que igual se puede (y debería ser) AFTER UPDATE. Porque en el caso de que no se confirme la actualización, no quieres que se guarde ese "intento de cambio".
No puedo confirmártelo, lo siento, pero haz ambas pruebas y una de las dos tiene que funcionar seguro.

Suerte. :-X
340  Programación / Bases de Datos / Re: Trigger SQL en: 29 Mayo 2020, 15:47 pm
MariaDB que creo que es MySQL

En ese caso no puedes usar las tablas temporales INSERTED y DELETED pues estas son propias de SQL Server.
El símil que existe en MySQL son las partículas NEW y OLD antes del nombre de una columna.

El primer trigger quedaría:
Código
  1. CREATE TRIGGER tr_persona_insert AFTER INSERT ON tb_persona FOR EACH ROW
  2.  INSERT INTO tb_logs VALUES ('insert', NEW.dni, NULL);
La claúsula FOR EACH ROW sirve para los casos en los que insertas varios registros con una única sentencia INSERT. Así el trigger se ejecutará una vez por cada registro. El opuesto sería FOR EACH STATEMENT.

El siguiente trigger no tiene ninguna complicación. Tendrás que usar OLD en vez de NEW.

Para el tercer trigger, el de UPDATE, tendrás que usar BEFORE en vez de AFTER para poder acceder tanto al valor nuevo (NEW) como al viejo (OLD).

Inténtalo y comenta si tienes algún problema.
Suerte. :-X
Páginas: 1 ... 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 [34] 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 ... 102
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines