• Miércoles 15 de Mayo de 2024, 04:41

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - pitukilloloco

Páginas: 1 2 [3] 4 5
51
C/C++ / Re: Ayuda Con Visual C++
« en: Miércoles 8 de Junio de 2005, 17:54 »
En esta liga puse un sencillo ejemplo de como manejar el ratón en modo consola. Ahí está el uso de la función sleep y de cómo poner un letrero en alguna parte de la consola. Espero te sirva
http://foro.elhacker.net/index.php/topic,68516.0.html

52
C/C++ / Re: Problema Con Matrices
« en: Miércoles 8 de Junio de 2005, 08:57 »
Es muy pequeña tu función pero contiene muchos errores. Primero. Solicitas memoria dinámica usando new pero nunca la liberas por lo que tu programa tendrá inconsistencias de memoria. Quizá sólo estabas probando que primero hiciera bien lo que quieres y después pornerle este código pero es buena práctica de programación siempre hacerlo aún en un código tan pequeño como este. Segundo. Te había dicho en el anterior comentario que la matriz matriz[2][2] realmente es un apuntador a una localidad de memoria en donde se encuentran consecutivamente los enteros de la matriz. Si quieres accesar al elemento [j] de la matriz usándola como apuntador a enteros entonces debes de hacerlo así *(matriz + 2*i + j) y no *(matriz + i + j). Tercero. Sigues confundiendo un apuntador a un apuntador a enteros int** f con una matriz bidimensional cuando quieres mostrar a f[j]. Tienes otro errores más pero mejor te preguntaría qué es lo que quieres hacer con la función para ponerte un ejemplo de acuerdo a eso. No te desanimes si todavía te confundes mucho con esto de los apuntadores en C y C++. Es una de las cosas inevitables con las que se topan todos los programadores en C y C++ más todo es cuestión de programar y programar para llegar a entenderlos.

53
C/C++ / Re: Problema Graficando Funciones
« en: Miércoles 8 de Junio de 2005, 08:12 »
Para escalar, digamos, los valores que van del intervalo (-950.45, 1527.63) a los valores del eje Y (10, 450) puedes hacerlo por medio de la ecuación de la recta entre dos puntos. La ecuación general de la recta entre los puntos (x1, y1) y (x2, y2) viene dada por la fórmula
Citar
y = [(y2 - y1) / (x2 - x1)] *  (x - x1) + y1
Para aplicar esta fórmula en la transformación del intervalo (-950.45, 1527.63) en el segundo (10, 450) debemos poner como primer punto (x1, y1) a (-950.45, 10) y a el segundo punto (x2, y2) como (1527.63, 450), entonces la fórmula quedaría como
Citar
y = [(450 - 10) / (1527.63 - (-950.45))] *  (x - (-950.45)) + 10
lo cual simplificando quedaría como
Citar
y = (440 / 2478.08) * (x + 950.45) + 10
si te fijas, al darle a esta ecuación el valor de x = -950.45, y tomaría el valor de 10, y al darle x = 1527.63, y tomaría el valor de 450. Así esta ecuación mapea el intervalo (-950.45, 1527.63) en el intervalo (10, 450) (claro que tienes que truncar los valores que da la ecuación a enteros para poder mandarlos a la función que pinta un pixel). En general, si tienes una función f(x) que va a tomar valores en el intervalo (a1, a2) y quieres graficarla, entonces tienes que hacer dos veces lo expuesto arriba. Tienes que mapear el intervalo (a1, a2) en el intervalo del eje X de la pantalla (puedes elegir de 0 a 639 u otro que tu elijas). Y tienes que mapear el intervalo (b1, b2) al eje Y de la pantalla, en donde b1 sería el mínimo valor que toma la función f(x) y b2 el máximo. En el caso particular tuyo de la primera función que se hace demasiado grande rápidamente, sólo tienes que escalar en el eje Y, ya que los valores que le das a la función van de 0 a 639, que es precisamente el intervalo del eje X de la pantalla.

54
C/C++ / Re: Problema Graficando Funciones
« en: Miércoles 8 de Junio de 2005, 04:41 »
La primera función que usas se dispara rápidamente dando valores muy grandes cuando la variable i apenas está tomando el número 10, por lo que estos no se veran en la pantalla cuando mandas a pintar los pixeles. Si quieres graficar los valores que toma esta función variando la i desde 0 hasta 639, debes de escalar los valores mínimo y máximo que pueda tomar la función en ese intervalo, con los valores mínimo y máximo de los valores en el eje Y de la pantalla.

55
C/C++ / Re: Criptografia Elgamal
« en: Miércoles 8 de Junio de 2005, 03:52 »
Si tu problema es convertir 8 bytes en un número, entonces no hay problema, pues C/C++ soportan el tipo long double, el cual creo haber leído en algún libro, que el estándar asegura que mínimamente debe de ser de 8 bytes. De cualquier manera, para asegurarme, en varios compiladores vi que tamaño me daba sizeof (long double) y estas fueron las respuestas:
Citar
Visual C++ 6           8 bytes
Dev C++ 4.9.9.2    12 bytes
Turbo C V2.01       10 bytes
cc de Red Hat 9    12 bytes
Borland C++ 3.1    10 bytes
y para convertir un long double teniendo los 8 bytes sólo se lo asignas con un cast o directamente desde un archivo. Por ejemplo, puedo leer de un archivo los 8 bytes y asignárselos a un long double así:
Código: Text
  1.  
  2. long double ld;
  3. fread (&ld, 8, 1, fp);
  4.  
  5.  
De lo de si conozco alguna clase que maneje número muy grandes pues no, pero en esta liga de la GNU http://directory.fsf.org/GNU/calc.html, de los fundadores del movimiento por el software libre, hay una calculadora hecha en C o C++ (no estoy seguro de en que lenguaje está hecha) que maneja números de presición arbitraria. Puedes descargar el fuente y tratar de ver qué algoritmos usaron para manejar esos números. De lo de adjuntar el archivo, si puedes hacerlo aquí mismo en este foro, sólo que ponen como requisito que el archivo sea a lo más de 128k. Puedes adjuntarlo usando el botón examinar que está antes de los botones Responder y Previsualizar el mensaje

56
C/C++ / Re: Problema Con Matrices
« en: Miércoles 8 de Junio de 2005, 02:28 »
Cuando declaras una matriz bidimensional int matriz[2][2] el compilador pone la dirección de memoria a partir de la cual comienzan los números de la matriz, por lo que es un error pensar que es un apuntador a un apuntador a enteros, cuando en realidad es un a puntador al comienzo de los enteros. Te muestro un ejemplo que ilustra esto
Código: Text
  1.  
  2. #include <stdio.h>
  3.  
  4. void recibematriz (int m[][2])
  5. {
  6.   printf ("%d\n", m[1][1]);
  7. }
  8.  
  9. void recibematriz (int *m)
  10. {
  11.   printf ("%d\n", *(m + 1));
  12. }
  13.  
  14. void main ()
  15. {
  16.   int matriz[2][2] = {{0,1},{1,5}};
  17.   recibematriz (matriz);
  18.   recibematriz ((int *)matriz);
  19. }
  20.  
  21.  
al correrlo te muestra un 5 en la primera línea y en la segunda un 1

57
C/C++ / Re: Listas Relacionadas Con Ficheros En C
« en: Martes 7 de Junio de 2005, 17:25 »
Si tu problema consiste en cómo escribir registros a un archivo, aquí te paso una liga, en este mismo foro, de un sencillo programa en C que efectúa altas, bajas y modificaciones en un archivo.
http://foros.solocodigo.com/index.php?showtopic=15531
 Si quieres insertar un registro en alguna posición del archivo, entonces necesariamente tienes que crear otro archivo; pasarle todos los registros a ese archivo hasta la posición donde quieres insertar el nuevo registro; insertarle el registro; copiar los registros restantes; borrar el archivo antiguo y renombrar el nuevo. Como ves, esto es muy ineficiente cada vez que insertes un registro. Una manera de hacerlo más eficiente es crear un archivo de índices que maneje el de los registros y cuando modificas dando de alta, insertando o dando de baja algun registro manterer ordenado el archivo de índices. ¿esto responde a tus dudas?

58
C/C++ / Re: Criptografia Elgamal
« en: Martes 7 de Junio de 2005, 16:45 »
No te entiendo bien lo que quieres. Dices que usaste una clase biginteger en Java. Yo no he programado en Java, por lo que no conozco tal clase, pero por el nombre puedo suponer que ahí manejan enteros más grandes que los normales proporcionados por el compilador. Si haces uso de esta característica y el compilador de C++ que usas no soporta enteros tan grandes como los que usas en el algoritmo, entonces debes de conseguirte o implementar una clase equivalente que haga lo mismo. Tu última consulta, de pasar una serie de caracteres a un número, me imagino que te refieres a una serie de caracteres que representan a un número ¿no?, porque, por ejemplo, la serie de caracteres "A123" no representan un número, pero "123", si. Si esta serie de caracteres lo quieres pasar a un número puedes usar la función atoi (ascii to integer) para números enteros y atof (ascii to float) para números reales. Ahora que si quieres convertir una serie de caracteres grande como esta "123456789123456789123456789" a un número, entonces, como te dije al principio, sólo consiguiendo una clase que maneje números grandes o impleméntandola tu mismo (lo cual es un ejercicio nada trivial) lo puedes conseguir. ¿Podrías poner ese algoritmo aquí para conocerlo y ver qué tan difícil está implementarlo en C++?

59
C/C++ / Re: Escr Y Leer Una Clase En Un File Aleatorio En C++
« en: Martes 7 de Junio de 2005, 16:23 »
Acabo de leer tu mensaje y primeramente me tienes que decir que compilador usas pues el cambiar el modo de compilación a K&R depende de eso.  Me puse a compilar de nuevo el programa y me di cuenta que había cometido dos errores (puede haber más pero no los he encontrado) al capturar. Estos son:
En las primeras líneas, despues del último #define hay que cambiar esta línea
Código: Text
  1.  
  2. struct node { int cnt; key[MM]; long ptr[MM+1]; };
  3.  
  4.  
por esta otra
Código: Text
  1.  
  2. struct node { int cnt, key[MM]; long ptr[MM+1]; };
  3.  
  4.  
(puse punto y coma en vez de poner sólo una coma). Y en la función ins, en la declaración de las variables, hay que cambiar la segunda línea
Código: Text
  1.  
  2.   long i, j, xnew, k_final, *n, *k, code;
  3.  
  4.  
por esta otra
Código: Text
  1.  
  2.   int i, j, xnew, k_final, *n, *k, code;
  3.  
  4.  
(puse long en vez de int)
Lo compilé sin errores ni advertencias con el Turbo C V2.01
Una de las diferencias de ANSI C con K&R es que en ANSI C debes de declarar a las funciones antes de poder usarlas, mientras que en K&R si una función no está declarada antes, el compilador asume que esta función regresa un valor entero. Otra diferencia es que al declarar o definir una función los tipos de los parámetros deben de darse dentro de los paréntesis de ANSI C, mientras que en K&R deben de darse afuera de los paréntesis. Otra diferencia es que en ANSI C debes de poner necesariamente el tipo que regresa la función, y en caso de que no regrese valor alguno, anteponer la palabra reservada void para indicar esto. En K&R, cuando no le pones el tipo que regresa la función se asume que regresa un entero. Por cierto la palabra reservada void no existe como tal en K&R. Existen otras muchas diferencias más pero estas son las más importantes para que cambies este programa que te puse a ANSI C. Me puse a hacerlo y te paso de nuevo el programa, con la correciones mencionadas al principio y para que compile en ANSI C. Sólo tuve que cambiar el nombre de la función delete por el nombre borrar para que no se confundiera con la palabra reservada de C++ que lleva el mismo nombre. El programa lo compilé con el Visual C++ 6 y con el Dev C++ sin ningún error.
Código: Text
  1.  
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <stdlib.h>
  5. #define M 2
  6. #define MM 4
  7. #define NIL (-1L)
  8. struct node { int cnt, key[MM]; long ptr[MM+1]; };
  9. typedef struct node NODE;
  10. NODE rootnode;
  11. long start[2], root = NIL, freelist = NIL;
  12. FILE *fptree;
  13. /************ declaración de funciones ***************/
  14. void search (int x);
  15. int binsearch (int x, int *a, int n);
  16. void found (long t, int i);
  17. void notfound (int x);
  18. void insert (int x);
  19. int ins (int x, long t, int *y, long *u);
  20. long getnode ();
  21. void freenode (long t);
  22. void readnode (long t, NODE *pnode);
  23. void writenode (long t, NODE *pnode);
  24. void rdstart ();
  25. void wrstart ();
  26. void error (char *str);
  27. void borrar (int x);
  28. int del (int x, long t);
  29. /*****************************************************/
  30. int main ()
  31. {  int x;
  32.   char ch, inpfilnam[30], treefilnam[30];
  33.   FILE *fpinp;
  34.  
  35.   printf ("Enter name of (binary) file for the B-tree; ");
  36.   scanf ("%s", treefilnam);
  37.   fptree = fopen (treefilnam, "rb+");    /* rb+ and wb+  */
  38.   if (fptree == NULL)            /* are system  */
  39.   {  fptree = fopen (treefilnam, "wb+");  /* dependent  */
  40.     wrstart ();
  41.   } else rdstart ();
  42.  
  43.   printf ("Enter name of (ASCII) input file (or NONE) : ");
  44.   scanf ("%s", inpfilnam);
  45.   fpinp = fopen (inpfilnam, "r");
  46.   if (fpinp != NULL)
  47.   {  while (fscanf (fpinp, "%d", &x) > 0) insert (x);
  48.     fclose (fpinp);
  49.   }
  50.  
  51.   while (1)
  52.   {  printf (
  53.     "\nDelete (D), Insert (I), Search (S) or Quit (Q): ");
  54.     do
  55.     {  ch = getchar (); ch = toupper (ch);
  56.     } while (ch != 'D' && ch != 'I' &&
  57.           ch != 'S' && ch != 'Q');
  58.     if (ch == 'Q') break;
  59.     printf ("Enter an integer: "); scanf ("%d", &x);
  60.     switch (ch)
  61.     {  case 'D': borrar (x); break;
  62.       case 'I': insert (x); break;
  63.       case 'S': search (x); break;
  64.     }
  65.   }
  66.   wrstart ();
  67.   fclose (fptree);
  68.   return EXIT_SUCCESS;
  69. }
  70.  
  71. void search (int x)
  72. {  int i, j, *k, n;
  73.   NODE nod;
  74.   long t = root;
  75.   printf ("Trace:\n");
  76.   while (t != NIL)
  77.   {  readnode (t, &nod);
  78.     k = nod.key; n = nod.cnt;
  79.     for (j = 0; j < n; j++) printf ("%d", k[j]);
  80.     printf ("\n");
  81.     i = binsearch (x, k, n);
  82.     if (i < n && x == k[i]) { found (t, i); return; }
  83.     t = nod.ptr[i];
  84.   }
  85.   notfound (x);
  86. }
  87.  
  88. int binsearch (int x, int *a, int n)
  89. /* Search array a[0], a[1], ..., a[n-1] for x    */
  90. /* Returned value:  0 if x <= a[0],  n if x > a[n-1],*/
  91. /*          or r, where a[r-1] < x <= a[r]  */
  92. {  int i, left, right;
  93.   if (x <= a[0]) return 0;
  94.   if (x > a[n-1]) return n;
  95.   left = 0; right = n-1;
  96.   while (right - left > 1)
  97.   {  i = right + left >> 1;
  98.     if (x <= a[i]) right = i; else left = i;
  99.   }
  100.   return right;
  101. }
  102.  
  103. void found (long t, int i)
  104. {  NODE nod;
  105.   printf ("Found in position %d ", i);
  106.   printf ("of node with contents: ");
  107.   readnode (t, &nod);
  108.   for (i = 0; i < nod.cnt; i++) printf (" %d", nod.key[i]);
  109.   printf ("\n");
  110. }
  111.  
  112. void notfound (int x)
  113. {  printf ("Item %d not found\n", x);
  114. }
  115.  
  116. void insert (int x)
  117. /*  Driver function for node insertion, called only in the
  118.   main program. Most of the work is delegated to 'ins'
  119. */
  120. {  long tnew, u, getnode ();
  121.   int xnew, code;
  122.   code = ins (x, root, &xnew, &tnew);
  123.   if (code == 2) printf ("Duplicate key %d ignored\n", x);
  124.   if (code) return;
  125.   u = getnode ();
  126.   rootnode.cnt = 1; rootnode.key[0] = xnew;
  127.   rootnode.ptr[0] = root; rootnode.ptr[1] = tnew;
  128.   root = u;
  129.   writenode (u, &rootnode);
  130. }
  131.  
  132. int ins (int x, long t, int *y, long *u)
  133. /*  Insert x in B-tree with root t. If not completely
  134.   successful, the integer *y and the pointer *u
  135.   remain to be inserted.
  136.   Returned value:
  137.     0 if insertion not completely successful.
  138.     1 if insertion successful.
  139.     2 if x is already present in B-tree.
  140. */
  141. {  long tnew, getnode (), p_final, *p;
  142.   int i, j, xnew, k_final, *n, *k, code;
  143.   NODE nod, newnod;
  144.   /*  Examine whether t is a pointer field in a leaf:
  145.   */
  146.   if (t == NIL) { *u = NIL; *y = x; return 0; }
  147.  
  148.   readnode (t, &nod);
  149.         n = &nod.cnt; k = nod.key; p = nod.ptr;
  150.  
  151.   /* Select pointer p[i] and try to insert x in
  152.     the subtree of which p[i] is the root;
  153.   */
  154.   i = binsearch (x, k, *n);
  155.   if (i < *n && x == k[i]) return 2;  /* Duplicate key */
  156.   code = ins (x, p[i], &xnew, &tnew);
  157.   if (code) return code;
  158.  
  159.   /* Insertion in subtree did not completely succed;
  160.     try to insert xnew and tnew in the current node:
  161.   */
  162.   if (*n < MM)
  163.   {  i = binsearch (xnew, k, *n);
  164.     for (j = *n; j > i; j--)
  165.     {  k[j] = k[j-1]; p[j+1] = p[j];
  166.     }
  167.     k[i] = xnew; p[i+1] = tnew; ++*n;
  168.     writenode (t, &nod); return 1;
  169.   }
  170.  
  171.   /* The current node was already full, so split it. Pass
  172.     item k[M] in the middle of the augmented sequence
  173.     back through parameter y, so that it can move
  174.     upward in the tree. Also, pass a pointer to the newly
  175.     created node back through u. Return 0, to report
  176.     that insertion was not completed:
  177.   */
  178.   if (i == MM) { k_final = xnew; p_final = tnew; } else
  179.   {  k_final = k[MM-1]; p_final = p[MM];
  180.     for (j = MM-1; j > i; j--)
  181.     {  k[j] = k[j-1]; p[j+1] = p[j];
  182.     }
  183.     k[i] = xnew; p[i+1] = tnew;
  184.   }
  185.   *y = k[M]; *n = M;
  186.  
  187.   *u = getnode (); newnod.cnt = M;
  188.   for (j = 0; j < M-1; j++)
  189.   {  newnod.key[j] = k[j+M+1]; newnod.ptr[j] = p[j+M+1];
  190.   }
  191.   newnod.ptr[M-1] = p[MM]; newnod.key[M-1] = k_final;
  192.   newnod.ptr[M] = p_final;
  193.   writenode (t, &nod); writenode (*u, &newnod); return 0;
  194. }
  195.  
  196. long getnode ()
  197. {  long t;
  198.   NODE nod;
  199.   if (freelist == NIL)
  200.   {  if (fseek (fptree, 0L, 2)) error ("fseek in getnode");
  201.     t = ftell (fptree);
  202.     writenode (t, &nod);  /* Reserve space on disk */
  203.   } else
  204.   {  t = freelist;
  205.     readnode (t, &nod);  /* To update freelist */
  206.     freelist = nod.ptr[0];
  207.   }
  208.   return t;
  209. }
  210.  
  211. void freenode (long t)
  212. {  NODE nod;
  213.   readnode (t, &nod);
  214.   nod.ptr[0] = freelist;
  215.   freelist = t;
  216.   writenode (t, &nod);
  217. }
  218.  
  219. void readnode (long t, NODE *pnode)
  220. {  if (t == root) { *pnode = rootnode; return; }
  221.   if (fseek (fptree, t, 0)) error ("fseek in readnode");
  222.   if (fread (pnode, sizeof (NODE), 1, fptree) == 0)
  223.     error ("fread in readnode");
  224. }
  225.  
  226. void writenode (long t, NODE *pnode)
  227. {  if (t == root) rootnode = *pnode;
  228.   if (fseek (fptree, t, 0)) error ("fseek in writenode");
  229.   if (fwrite (pnode, sizeof (NODE), 1, fptree) == 0)
  230.     error ("fwrite in writenode");
  231. }
  232.  
  233. void rdstart ()
  234. {  if (fseek (fptree, 0L, 0)) error ("fseek in rdstart");
  235.   if (fread (start, sizeof (long), 2, fptree) == 0)
  236.     error ("fread in rdstart");
  237.   readnode (start[0], &rootnode);
  238.   root = start[0]; freelist = start[1];
  239. }
  240.  
  241. void wrstart ()
  242. {  start[0] = root; start[1] = freelist;
  243.   if (fseek (fptree, 0L, 0)) error ("fseek in wrstart");
  244.   if (fwrite (start, sizeof (long), 2, fptree) == 0)
  245.     error ("fwrite in wrstart");
  246.   if (root != NIL) writenode (root, &rootnode);
  247. }
  248.  
  249. void error (char *str)
  250. {  printf ("\nError: %s\n", str);
  251.   exit (EXIT_FAILURE);
  252. }
  253.  
  254. void borrar (int x)
  255. /* Driver function for node deletion called only in the
  256.   main program. Most of the work is delegated to "del".
  257. */
  258. {  int code;
  259.   long newroot;
  260.   code = del (x, root);
  261.   if (code == 2) printf ("%d not found\n", x);
  262.   if (code) return;
  263.   /* 0 = underflow; 1 = success; 2 = key not found   */
  264.   /* If underflow, decrease the height of the three: */
  265.   newroot = rootnode.ptr[0]; freenode (root);
  266.   if (newroot != NIL) readnode (newroot, &rootnode);
  267.   root = newroot;
  268. }
  269.  
  270. int del (int x, long t)
  271. /* Delete item x in B-tree with root t.
  272.    Returned value:
  273.    0 = underflow, 1 = success, 2 = not found
  274. */
  275. {  int i, j, *k, *n, *item, code,
  276.     *nleft, *nright, *lkey, *rkey, borrowleft, nq, *addr;
  277.   long *p, left, right, *lptr, *rptr, q, q1;
  278.   NODE nod, nod1, nod2;
  279.   if (t == NIL) return 2;
  280.   readnode (t, &nod);
  281.   n = &nod.cnt; k = nod.key; p = nod.ptr;
  282.   i = binsearch (x, k, *n);
  283.   if (p[0] == NIL)  /* *t is a leaf */
  284.   {  if (i == *n || x < k[i]) return 2;
  285.     /* x is now equal to k[i], located in a leaf: */
  286.     for (j = i+1; j < *n; j++)
  287.     {  k[j-1] = k[j]; p[j] = p[j+1];
  288.     }
  289.     --*n;
  290.     writenode (t, &nod);
  291.     return *n >= (t == root ? 1 : M);
  292.   }
  293.   /* *t is an interior node (not a leaf): */
  294.   item = k+i; left = p[i]; readnode (left, &nod1);
  295.   nleft = &nod1.cnt;
  296.   if (i < *n && x == *item)
  297.   { /* x found in interior node.             */
  298.     /* Go to left child *p[i] and then follow a path   */
  299.     /* all the way to a leaf, using rightmost branches */
  300.     q = p[i]; readnode (q, &nod1); nq = nod1.cnt;
  301.     while (q1 = nod1.ptr[nq], q1 != NIL)
  302.     {  q = q1; readnode (q, &nod1); nq = nod1.cnt;
  303.     }
  304.     /* Exchange k[i] with the rightmost item in
  305.       that leaf:
  306.     */
  307.     addr = nod1.key + nq - 1;
  308.     *item = *addr; *addr = x;
  309.     writenode (t, &nod); writenode (q, &nod1);
  310.   }
  311.   /* Delete x in subtree with root p[i] */
  312.   code = del (x, left);
  313.   if (code) return code;
  314.   /* Underflow: borrow, and, if necessary, merge */
  315.   borrowleft = i == *n;
  316.   if (borrowleft)  /* p[i] is rightmost pointer in *p */
  317.   {  item = k+i-1; left = p[i-1]; right = p[i];
  318.     readnode (left, &nod1);
  319.     nleft = &nod1.cnt;
  320.   } else right = p[i+1];
  321.   readnode (left, &nod1);
  322.   readnode (right, &nod2);
  323.   nright = &nod2.cnt;
  324.   lkey = nod1.key; rkey = nod2.key;
  325.   lptr = nod1.ptr; rptr = nod2.ptr;
  326.   if (borrowleft)  /* This is an exception */
  327.   {  rptr[*nright + 1] = rptr[*nright];
  328.     for (j = *nright; j > 0; j--)
  329.     {  rkey[j] = rkey[j-1];
  330.       rptr[j] = rptr[j-1];
  331.     }
  332.     ++*nright;
  333.     rkey[0] = *item; rptr[0] = lptr[*nleft];
  334.     *item = lkey[*nleft - 1];
  335.     if (--*nleft >= M)
  336.     {  writenode (t, &nod); writenode (left, &nod1);
  337.       writenode (right, &nod2);
  338.       return 1;
  339.     }
  340.   } else
  341.   if (*nright > M)  /* Borrow from right sibling: */
  342.   {  lkey[M-1] = *item; lptr[M] = rptr[0]; *item = rkey[0];
  343.     ++*nleft; --*nright;
  344.     for (j = 0; j < *nright; j++)
  345.     {  rptr[j] = rptr[j+1]; rkey[j] = rkey[j+1];
  346.     }
  347.     rptr[*nright] = rptr[*nright + 1];
  348.     writenode (t, &nod); writenode (left, &nod1);
  349.     writenode (right, &nod2);
  350.     return 1;
  351.   }
  352.   /* Merge */
  353.   lkey[M-1] = *item; lptr[M] = rptr[0];
  354.   for (j = 0; j < M; j++)
  355.   {  lkey[M+j] = rkey[j]; lptr[M+j+1] = rptr[j+1];
  356.   }
  357.   *nleft = MM;
  358.   freenode (right);
  359.   for (j = i+1; j < *n; j++) { k[j-1] = k[j]; p[j] = p[j+1]; }
  360.   --*n;
  361.   writenode (t, &nod);
  362.   writenode (left, &nod1);
  363.   return *n <= (t == root ? 1 : M);
  364. }
  365.  
  366.  

60
C/C++ / Re: Escr Y Leer Una Clase En Un File Aleatorio En C++
« en: Lunes 6 de Junio de 2005, 22:07 »
Bueno, lo prometido es deuda. Te pongo el código que maneja un árbol-B en disco. El programa lo saqué del libro Programs and Data Structures in C del autor Leendert Ammeraal. En él sólo introduce enteros en los nodos del árbol, pero tú lo podrías modificar fácilmente para que introduzca otras cosas. El fuente está escrito siguiendo el modelo K&R, o sea, como se escribían los programas antes de que se  hiciera estándar el ANSI C, por lo que si quieres que el programa te compile sin error debes de modificar las banderas para que compile en modo K&R. Sólo lo capturé y probé que compilaba sin errores pero no le he corrido para ver si hace bien los árboles, por lo que debes de probarlo antes de incorporarlo a tu proyecto.
Código: Text
  1.  
  2. /* DISKTREE.C:
  3.   Demonstration program for a B-tree on disk.
  4.   After building the tree by reading integer from a
  5.   file, we can repeteadly search the three for a
  6.   given integer. Each time, a search path from root
  7.   to leaf is displayed. We can also update the B-three
  8.   interactively
  9. */
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #define M 2
  13. #define MM 4
  14. #define NIL (-1L)
  15. struct node { int cnt; key[MM]; long ptr[MM+1]; };
  16. typedef struct node NODE;
  17. NODE rootnode;
  18. long start[2], root = NIL, freelist = NIL;
  19. FILE *fptree;
  20.  
  21. main ()
  22. {  int x;
  23.   char ch, inpfilnam[30], treefilnam[30];
  24.   FILE *fpinp;
  25.  
  26.   printf ("Enter name of (binary) file for the B-tree; ");
  27.   scanf ("%s", treefilnam);
  28.   fptree = fopen (treefilnam, "rb+");    /* rb+ and wb+  */
  29.   if (fptree == NULL)            /* are system  */
  30.   {  fptree = fopen (treefilnam, "wb+");  /* dependent  */
  31.     wrstart ();
  32.   } else rdstart ();
  33.  
  34.   printf ("Enter name of (ASCII) input file (or NONE) : ");
  35.   scanf ("%s", inpfilnam);
  36.   fpinp = fopen (inpfilnam, "r");
  37.   if (fpinp != NULL)
  38.   {  while (fscanf (fpinp, "%d", &x) > 0) insert (x);
  39.     fclose (fpinp);
  40.   }
  41.  
  42.   while (1)
  43.   {  printf (
  44.     "\nDelete (D), Insert (I), Search (S) or Quit (Q): ");
  45.     do
  46.     {  ch = getchar (); ch = toupper (ch);
  47.     } while (ch != 'D' && ch != 'I' &&
  48.           ch != 'S' && ch != 'Q');
  49.     if (ch == 'Q') break;
  50.     printf ("Enter an integer: "); scanf ("%d", &x);
  51.     switch (ch)
  52.     {  case 'D': delete (x); break;
  53.       case 'I': insert (x); break;
  54.       case 'S': search (x); break;
  55.     }
  56.   }
  57.   wrstart ();
  58.   fclose (fptree);
  59. }
  60.  
  61. search (x) int x;
  62. {  int i, j, *k, n;
  63.   NODE nod;
  64.   long t = root;
  65.   printf ("Trace:\n");
  66.   while (t != NIL)
  67.   {  readnode (t, &nod);
  68.     k = nod.key; n = nod.cnt;
  69.     for (j = 0; j < n; j++) printf ("%d", k[j]);
  70.     printf ("\n");
  71.     i = binsearch (x, k, n);
  72.     if (i < n && x == k[i]) { found (t, i); return; }
  73.     t = nod.ptr[i];
  74.   }
  75.   notfound (x);
  76. }
  77.  
  78. int binsearch (x, a, n) int x, *a, n;
  79. /* Search array a[0], a[1], ..., a[n-1] for x    */
  80. /* Returned value:  0 if x <= a[0],  n if x > a[n-1],*/
  81. /*          or r, where a[r-1] < x <= a[r]  */
  82. {  int i, left, right;
  83.   if (x <= a[0]) return 0;
  84.   if (x > a[n-1]) return n;
  85.   left = 0; right = n-1;
  86.   while (right - left > 1)
  87.   {  i = right + left >> 1;
  88.     if (x <= a[i]) right = i; else left = i;
  89.   }
  90.   return right;
  91. }
  92.  
  93. found (t, i) long t; int i;
  94. {  NODE nod;
  95.   printf ("Found in position %d ", i);
  96.   printf ("of node with contents: ");
  97.   readnode (t, &nod);
  98.   for (i = 0; i < nod.cnt; i++) printf (" %d", nod.key[i]);
  99.   printf ("\n");
  100. }
  101.  
  102. notfound (x) int x;
  103. {  printf ("Item %d not found\n", x);
  104. }
  105.  
  106. insert (x) int x;
  107. /*  Driver function for node insertion, called only in the
  108.   main program. Most of the work is delegated to 'ins'
  109. */
  110. {  long tnew, u, getnode ();
  111.   int xnew, code;
  112.   code = ins (x, root, &xnew, &tnew);
  113.   if (code == 2) printf ("Duplicate key %d ignored\n", x);
  114.   if (code) return;
  115.   u = getnode ();
  116.   rootnode.cnt = 1; rootnode.key[0] = xnew;
  117.   rootnode.ptr[0] = root; rootnode.ptr[1] = tnew;
  118.   root = u;
  119.   writenode (u, &rootnode);
  120. }
  121.  
  122. int ins (x, t, y, u) int x, *y; long t, *u;
  123. /*  Insert x in B-tree with root t. If not completely
  124.   successful, the integer *y and the pointer *u
  125.   remain to be inserted.
  126.   Returned value:
  127.     0 if insertion not completely successful.
  128.     1 if insertion successful.
  129.     2 if x is already present in B-tree.
  130. */
  131. {  long tnew, getnode (), p_final, *p;
  132.   long i, j, xnew, k_final, *n, *k, code;
  133.   NODE nod, newnod;
  134.   /*  Examine whether t is a pointer field in a leaf:
  135.   */
  136.   if (t == NIL) { *u = NIL; *y = x; return 0; }
  137.  
  138.   readnode (t, &nod);
  139.         n = &nod.cnt; k = nod.key; p = nod.ptr;
  140.  
  141.   /* Select pointer p[i] and try to insert x in
  142.     the subtree of which p[i] is the root;
  143.   */
  144.   i = binsearch (x, k, *n);
  145.   if (i < *n && x == k[i]) return 2;  /* Duplicate key */
  146.   code = ins (x, p[i], &xnew, &tnew);
  147.   if (code) return code;
  148.  
  149.   /* Insertion in subtree did not completely succed;
  150.     try to insert xnew and tnew in the current node:
  151.   */
  152.   if (*n < MM)
  153.   {  i = binsearch (xnew, k, *n);
  154.     for (j = *n; j > i; j--)
  155.     {  k[j] = k[j-1]; p[j+1] = p[j];
  156.     }
  157.     k[i] = xnew; p[i+1] = tnew; ++*n;
  158.     writenode (t, &nod); return 1;
  159.   }
  160.  
  161.   /* The current node was already full, so split it. Pass
  162.     item k[M] in the middle of the augmented sequence
  163.     back through parameter y, so that it can move
  164.     upward in the tree. Also, pass a pointer to the newly
  165.     created node back through u. Return 0, to report
  166.     that insertion was not completed:
  167.   */
  168.   if (i == MM) { k_final = xnew; p_final = tnew; } else
  169.   {  k_final = k[MM-1]; p_final = p[MM];
  170.     for (j = MM-1; j > i; j--)
  171.     {  k[j] = k[j-1]; p[j+1] = p[j];
  172.     }
  173.     k[i] = xnew; p[i+1] = tnew;
  174.   }
  175.   *y = k[M]; *n = M;
  176.  
  177.   *u = getnode (); newnod.cnt = M;
  178.   for (j = 0; j < M-1; j++)
  179.   {  newnod.key[j] = k[j+M+1]; newnod.ptr[j] = p[j+M+1];
  180.   }
  181.   newnod.ptr[M-1] = p[MM]; newnod.key[M-1] = k_final;
  182.   newnod.ptr[M] = p_final;
  183.   writenode (t, &nod); writenode (*u, &newnod); return 0;
  184. }
  185.  
  186. long getnode ()
  187. {  long t;
  188.   NODE nod;
  189.   if (freelist == NIL)
  190.   {  if (fseek (fptree, 0L, 2)) error ("fseek in getnode");
  191.     t = ftell (fptree);
  192.     writenode (t, &nod);  /* Reserve space on disk */
  193.   } else
  194.   {  t = freelist;
  195.     readnode (t, &nod);  /* To update freelist */
  196.     freelist = nod.ptr[0];
  197.   }
  198.   return t;
  199. }
  200.  
  201. freenode (t) long t;
  202. {  NODE nod;
  203.   readnode (t, &nod);
  204.   nod.ptr[0] = freelist;
  205.   freelist = t;
  206.   writenode (t, &nod);
  207. }
  208.  
  209. readnode (t, pnode) long t; NODE *pnode;
  210. {  if (t == root) { *pnode = rootnode; return; }
  211.   if (fseek (fptree, t, 0)) error ("fseek in readnode");
  212.   if (fread (pnode, sizeof (NODE), 1, fptree) == 0)
  213.     error ("fread in readnode");
  214. }
  215.  
  216. writenode (t, pnode) long t; NODE *pnode;
  217. {  if (t == root) rootnode = *pnode;
  218.   if (fseek (fptree, t, 0)) error ("fseek in writenode");
  219.   if (fwrite (pnode, sizeof (NODE), 1, fptree) == 0)
  220.     error ("fwrite in writenode");
  221. }
  222.  
  223. rdstart ()
  224. {  if (fseek (fptree, 0L, 0)) error ("fseek in rdstart");
  225.   if (fread (start, sizeof (long), 2, fptree) == 0)
  226.     error ("fread in rdstart");
  227.   readnode (start[0], &rootnode);
  228.   root = start[0]; freelist = start[1];
  229. }
  230.  
  231. wrstart ()
  232. {  start[0] = root; start[1] = freelist;
  233.   if (fseek (fptree, 0L, 0)) error ("fseek in wrstart");
  234.   if (fwrite (start, sizeof (long), 2, fptree) == 0)
  235.     error ("fwrite in wrstart");
  236.   if (root != NIL) writenode (root, &rootnode);
  237. }
  238.  
  239. error (str) char *str;
  240. {  printf ("\nError: %s\n", str);
  241.   exit (1);
  242. }
  243.  
  244. delete (x) int x;
  245. /* Driver function for node deletion called only in the
  246.   main program. Most of the work is delegated to "del".
  247. */
  248. {  int code;
  249.   long newroot;
  250.   code = del (x, root);
  251.   if (code == 2) printf ("%d not found\n", x);
  252.   if (code) return;
  253.   /* 0 = underflow; 1 = success; 2 = key not found   */
  254.   /* If underflow, decrease the height of the three: */
  255.   newroot = rootnode.ptr[0]; freenode (root);
  256.   if (newroot != NIL) readnode (newroot, &rootnode);
  257.   root = newroot;
  258. }
  259.  
  260. int del (x, t) int x; long t;
  261. /* Delete item x in B-tree with root t.
  262.    Returned value:
  263.    0 = underflow, 1 = success, 2 = not found
  264. */
  265. {  int i, j, *k, *n, *item, code,
  266.     *nleft, *nright, *lkey, *rkey, borrowleft, nq, *addr;
  267.   long *p, left, right, *lptr, *rptr, q, q1;
  268.   NODE nod, nod1, nod2;
  269.   if (t == NIL) return 2;
  270.   readnode (t, &nod);
  271.   n = &nod.cnt; k = nod.key; p = nod.ptr;
  272.   i = binsearch (x, k, *n);
  273.   if (p[0] == NIL)  /* *t is a leaf */
  274.   {  if (i == *n || x < k[i]) return 2;
  275.     /* x is now equal to k[i], located in a leaf: */
  276.     for (j = i+1; j < *n; j++)
  277.     {  k[j-1] = k[j]; p[j] = p[j+1];
  278.     }
  279.     --*n;
  280.     writenode (t, &nod);
  281.     return *n >= (t == root ? 1 : M);
  282.   }
  283.   /* *t is an interior node (not a leaf): */
  284.   item = k+i; left = p[i]; readnode (left, &nod1);
  285.   nleft = &nod1.cnt;
  286.   if (i < *n && x == *item)
  287.   { /* x found in interior node.             */
  288.     /* Go to left child *p[i] and then follow a path   */
  289.     /* all the way to a leaf, using rightmost branches */
  290.     q = p[i]; readnode (q, &nod1); nq = nod1.cnt;
  291.     while (q1 = nod1.ptr[nq], q1 != NIL)
  292.     {  q = q1; readnode (q, &nod1); nq = nod1.cnt;
  293.     }
  294.     /* Exchange k[i] with the rightmost item in
  295.       that leaf:
  296.     */
  297.     addr = nod1.key + nq - 1;
  298.     *item = *addr; *addr = x;
  299.     writenode (t, &nod); writenode (q, &nod1);
  300.   }
  301.   /* Delete x in subtree with root p[i] */
  302.   code = del (x, left);
  303.   if (code) return code;
  304.   /* Underflow: borrow, and, if necessary, merge */
  305.   borrowleft = i == *n;
  306.   if (borrowleft)  /* p[i] is rightmost pointer in *p */
  307.   {  item = k+i-1; left = p[i-1]; right = p[i];
  308.     readnode (left, &nod1);
  309.     nleft = &nod1.cnt;
  310.   } else right = p[i+1];
  311.   readnode (left, &nod1);
  312.   readnode (right, &nod2);
  313.   nright = &nod2.cnt;
  314.   lkey = nod1.key; rkey = nod2.key;
  315.   lptr = nod1.ptr; rptr = nod2.ptr;
  316.   if (borrowleft)  /* This is an exception */
  317.   {  rptr[*nright + 1] = rptr[*nright];
  318.     for (j = *nright; j > 0; j--)
  319.     {  rkey[j] = rkey[j-1];
  320.       rptr[j] = rptr[j-1];
  321.     }
  322.     ++*nright;
  323.     rkey[0] = *item; rptr[0] = lptr[*nleft];
  324.     *item = lkey[*nleft - 1];
  325.     if (--*nleft >= M)
  326.     {  writenode (t, &nod); writenode (left, &nod1);
  327.       writenode (right, &nod2);
  328.       return 1;
  329.     }
  330.   } else
  331.   if (*nright > M)  /* Borrow from right sibling: */
  332.   {  lkey[M-1] = *item; lptr[M] = rptr[0]; *item = rkey[0];
  333.     ++*nleft; --*nright;
  334.     for (j = 0; j < *nright; j++)
  335.     {  rptr[j] = rptr[j+1]; rkey[j] = rkey[j+1];
  336.     }
  337.     rptr[*nright] = rptr[*nright + 1];
  338.     writenode (t, &nod); writenode (left, &nod1);
  339.     writenode (right, &nod2);
  340.     return 1;
  341.   }
  342.   /* Merge */
  343.   lkey[M-1] = *item; lptr[M] = rptr[0];
  344.   for (j = 0; j < M; j++)
  345.   {  lkey[M+j] = rkey[j]; lptr[M+j+1] = rptr[j+1];
  346.   }
  347.   *nleft = MM;
  348.   freenode (right);
  349.   for (j = i+1; j < *n; j++) { k[j-1] = k[j]; p[j] = p[j+1]; }
  350.   --*n;
  351.   writenode (t, &nod);
  352.   writenode (left, &nod1);
  353.   return *n <= (t == root ? 1 : M);
  354. }
  355.  
  356.  

61
C/C++ / Re: Escr Y Leer Una Clase En Un File Aleatorio En C++
« en: Domingo 5 de Junio de 2005, 21:44 »
Si te fijas en el código que te puse, al modificar una persona, encuentra a esta buscando secuencialmente en el archivo su matricula. ¿qué sucede si la encuentra? pues tengo que utilizar a la función fseek para regresar el apuntador al archivo (un apuntador que se usa internamente en las operaciones de lectura y escritura) al comienzo de donde se encuentra el alumno, ya que al leerlo este apuntador se incrementa hasta el total de bytes leídos. Esto lo hago con la instrucción
Código: Text
  1.  
  2.       fseek (globfp, -1L * sizeof (a), SEEK_CUR);
  3.  
  4.  
¿qué significa esto? pues que estoy moviendo hacia atrás (por eso lo multiplico por -1) el apuntador al archivo tantos bytes como haya en la estructura a, a partir de la posición actual del apuntador del archivo, esto lo indico con la constante SEEK_CUR, lo cual quiere decir que estoy haciendo un desplazamiento relativo a donde se encuentra el apuntador del archivo. Si tu quieres moverte a la posición donde se encuentra, por ejemplo el alumnoi #8, entonces tengo que hacer un desplazamiento absoluto del apuntador al archivo, a partir del comienzo. Esto se consigue de esta manera
Código: Text
  1.  
  2.       fseek (globfp, (8 - 1) * sizeof (a), SEEK_SET);
  3.  
  4.  
En general, si tu tienes declarada alguna estructura y tienes almacenado en disco elementos de ella, la manera para accesar al elemento n de ella es
Código: Text
  1.  
  2.       fseek (fp, (n - 1) * sizeof (struct nombre_strut), SEEK_SET);
  3.  
  4.  
espero que esta información te ayude con tu problema. Lo de implementar índices hash es relativamente sencillo, pero sobre todo laborioso, pero si piensas implementar árboles-B estos no son de ningún modo sencillos de implementar y los algoritmos para implementar las altas, bajas y modificaciones son muy complejos. Si te interesa por ahí tengo un libro ya viejo sobre estructuras de datos en C en donde viene un sencillo ejemplo de un programa en C y que implementa un árbol-B en disco, sólo que tendría que capturarlo y quizá hasta mañana te lo tendría.

62
C/C++ / Re: Ayuda Con Sumatorias
« en: Domingo 5 de Junio de 2005, 21:15 »
Me parece que estás implementado mal el polinomio. Vamos analizando que valores toman tus variable al entrar y ejecutar el primer ciclo. Los valores de tus variables al comenzar son
Código: Text
  1.  
  2. suma=0;
  3. signo=1, t1=1, t4=1, n=0;
  4.  
  5.  
y el valor de la variable x que introduces por el teclado. Las líneas que tienes dentro del ciclo son
Código: Text
  1.  
  2. n=n+1;
  3. t1=t1*x*x;
  4. t2=x;
  5. t3=2*n-1;
  6. termino=t1/(t2*t3*t4)
  7. suma=suma+signo*termino;
  8. t4=t4*2*n*(2*n+1);
  9. signo=-signo;
  10.  
  11.  
así que sustituyendo sus valores serán
Código: Text
  1.  
  2. n=1;
  3. t1=x^2;
  4. t2=x;
  5. t3=1;
  6. termino=x;
  7. suma=x;
  8. t4=6 = 3!;
  9. signo=-1;
  10.  
  11.  
Hasta aquí todo va bien, ya tienes al primer término del polinomio cuyo valor es x, pero en la siguiente iteración estos serán sus valores
Código: Text
  1.  
  2. n=2;
  3. t1=x^2*x*x = x^4;
  4. t2=x;   // fíjate que este valor nunca cambia o sea que no tiene sentido poner
  5.            // esta asignación dentro del ciclo
  6. t3=2*n-1;
  7. termino=x4/(x*1*6) = x^3/3!; // debió ser x^3/3*3!
  8. suma=x-x^3/3!;
  9. t4=6*2*2*(2*2+1);
  10. signo=1;
  11.  
  12.  
que como ves ya se aleja del resultado.
Aquí está una manera en que lo haría yo
Código: Text
  1.  
  2.   int x;
  3.   cout<<"ingrese el valor de x ";cin>>x;
  4.   const int DELTA = 0.00000001;
  5.   float x2 = x * x;
  6.   int n = 0;
  7.   float xexp = x; // Contiene el término x^n, al principio
  8.           // tiene el valor de x; entrando al ciclo
  9.           // su valor será x * x2 = x * x* x = x^3;
  10.           // después xexp * x2 = x^3 * x * x = x^5, etc.
  11.   float factimp = 1;  // Tiene el factorial impar. Al comienzo
  12.             // tiene 1; al entrar al ciclo su valor será
  13.             // 1 * (n + 2) * (n + 3) = 1 * 2 * 3 = 3!
  14.             // en la siguiente iteración n se incrementa en 2
  15.             // y factimp es igual a 3! * (n + 2) * (n + 3)
  16.             // o sea 3! * 4 * 5 = 5!, etc
  17.   int signo = -1;
  18.   suma = x;
  19.   int termino = 1;
  20.   for (int n = 0; termino >= DELTA; n += 2) {
  21.     xexp *= x2;
  22.     factimp *= (n + 2) * (n + 3);
  23.     termino = xexp / ((n + 3) * factimp);
  24.     suma += signo * termino;
  25.     n += 2;
  26.     signo *= -1;
  27.   }
  28.  
  29.  
es una entre muchas maneras de implementarlo.

63
C/C++ / Re: Escr Y Leer Una Clase En Un File Aleatorio En C++
« en: Domingo 5 de Junio de 2005, 16:32 »
Bueno, con el ejemplo yo sólo pretendía que supieras cómo usar las funciones de la librería estándar de entrada y salida de C, las funciones para abrir (fopen), cerrar (fclose), leer (fread) y escribir (fwrite) en un archivo, y de paso también te mostré cómo posicionarte en algún punto del archivo con la función fseek. En base a estas funciones (y a otras que no mostré aquí pero que puedes investigar en cualquier libro de texto o en internet, como ferror, fflush, etc.) puedes construir tu base de datos como lo desees ya sea usando índices con el método hash que mencionas, pero hay otras formas de hacerlo como usar índices por medio de un árbol binario, por árboles-B, etc., pero entonces, ya no te estaría poniendo un ejemplo sino te estaría resolviendo tu ejercicio, aparte que nunca mencionaste que ibas a usar índices ni que ibas a usar el método hash. Aquí está textualmente lo que pusiste al principio de tu duda en este foro
Citar
Les agradeseria si alguien me pudiera dar un ejemplo de como hacer lecturas y escrituras en un archivo de acceso aleatorio, ...
¿no creerás que soy adivino, verdad?

64
C/C++ / Re: Escr Y Leer Una Clase En Un File Aleatorio En C++
« en: Sábado 4 de Junio de 2005, 01:11 »
Este es un ejemplo sencillo que hice que da de alta el nombre y la matrícula de un alumno. Lo puedes modificar fácilmente para que utilices la estructura que quieres. En el ejemplo muestro cómo dar de alta, de baja y modificar un alumno. Al dar de baja sólo estoy poniendo una marca de borrado pero no estoy en realidad borrando el alumno del archivo. Esto lo puedes hacer pasando todos los registro que no tengan la marca a un nuevo archivo, borrar el original y renombrar el nuevo. Ya no hice esto porque el ejemplo lo quise hacer lo más sencillo posible.
Código: Text
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. enum { FALSO = 0, VERDADERO = 1 };
  7. #define BAJA -1
  8.  
  9. struct alumno {
  10.   char nombre [80];
  11.   int matricula;
  12. };
  13.  
  14. FILE *globfp;
  15.  
  16. void AbreBase (char *nombase)
  17. {
  18.   if ((globfp = fopen (nombase, "r+b")) == NULL)
  19.     if ((globfp = fopen (nombase, "w+b")) == NULL) {
  20.       fprintf (stderr, "Error al crear el archivo %s\n", nombase);
  21.       exit (EXIT_FAILURE);
  22.     }
  23. }
  24.  
  25. void CierraBase ()
  26. {
  27.   fclose (globfp);
  28. }
  29.  
  30. int Alta (char *nombre, int matricula)
  31. {
  32.   struct alumno a;
  33.  
  34.   strcpy (a.nombre, nombre);
  35.   a.matricula = matricula;
  36.  
  37.   fseek (globfp, 0L, SEEK_END);
  38.   fwrite (&a, sizeof (a), 1, globfp);
  39.  
  40.   return VERDADERO;
  41. }
  42.  
  43. int Modifica (int matri, char *nombre, int matricula)
  44. {
  45.   struct alumno a;
  46.  
  47.   fseek (globfp, 0L, SEEK_SET);
  48.   while (VERDADERO) {
  49.     fread (&a, sizeof (a), 1, globfp);
  50.     if (feof (globfp))
  51.       break;
  52.     if (a.matricula == matri) {
  53.       strcpy (a.nombre, nombre);
  54.       a.matricula = matricula;
  55.       fseek (globfp, -1L * sizeof (a), SEEK_CUR);
  56.       fwrite (&a, sizeof (a), 1, globfp);
  57.       return VERDADERO;
  58.     }
  59.   }
  60.   return FALSO;
  61. }
  62.  
  63. int Baja (int matricula)
  64. {
  65.   return Modifica (matricula, "", BAJA);
  66. }
  67.  
  68. void VerBase ()
  69. {
  70.   struct alumno a;
  71.  
  72.   fseek (globfp, 0L, SEEK_SET);
  73.   while (VERDADERO) {
  74.     fread (&a, sizeof (a), 1, globfp);
  75.     if (feof (globfp))
  76.       break;
  77.     if (a.matricula != BAJA)
  78.       printf ("#%d\t%s\n", a.matricula, a.nombre);
  79.   }
  80. }
  81.  
  82. int main ()
  83. {
  84.   char *datos[] = {
  85.     "Pepa", "1",
  86.     "Pepe", "2",
  87.     "Ana", "3",
  88.     "Pablo", "4",
  89.     "Eva", "5",
  90.     "Tito", "6",
  91.     "Ema", "7",
  92.     "Quico", "8",
  93.     "Ines", "9",
  94.     "Pedro", "10",
  95.   };
  96.   int i;
  97.  
  98.   AbreBase ("mibase.bin");
  99.   for (i = 0; i < sizeof (datos) / sizeof (*datos); i += 2)
  100.     Alta (datos[i], atoi (datos[i + 1]));
  101.  
  102.   printf ("--------------- ");
  103.   printf ("Alumnos dados de alta\n");
  104.   VerBase ();
  105.   Modifica (1, "Pepa Luna", 100);
  106.   Modifica (5, "Eva Sol", 500);
  107.   Modifica (10, "Pedro Estrella", 1000);
  108.   Baja (2);
  109.   Baja (8);
  110.   printf ("--------------- ");
  111.   printf ("Base de datos despu\x82s de modificar y dar de baja\n");
  112.   VerBase ();
  113.   CierraBase ();
  114.  
  115.   exit (EXIT_SUCCESS);
  116. }
  117.  
  118.  

65
C/C++ / Re: Manejo Vectores
« en: Viernes 3 de Junio de 2005, 19:25 »
¿me puedes decir qué compilador estás usando? traté de compilarlo con estos 4 compiladores que tengo en mi pc y en todos me marcó errorres:
Turbo C V2.01
Borland C++ 3.1
Dev C++ 4.9.9.2
Visual C++ 6

66
C/C++ / Re: Escr Y Leer Una Clase En Un File Aleatorio En C++
« en: Viernes 3 de Junio de 2005, 15:21 »
Yo te podría dar un ejemplo pero usando las funciones de la librería estándar cuyo encabezado es stdio.h. Las funciones para manejar flujos que están definidas en iostream.h (donde está definida la clase ios) siempre me ha dado flojera estudiar cómo funcionan pues cuando quiero escribir y leer de un archivo con las primeras funciones que te menciono me ha bastado. El mismo creador del lenguaje Bjarne Stroustrup, reconoce en su libro El Lenguaje de Programación C++ que las funciones de flujo son más seguras con respecto a los tipos pero que las de stdio.h son más sencillas de manejar.

67
C/C++ / Re: Creacion De Menus De Texto.
« en: Viernes 3 de Junio de 2005, 14:58 »
Acabo de fijarme en el archivo que adjuntaste y es el mismo que yo puse en el foro de la liga que te mencioné. Si quieres enteder el programa te deberías de conseguir el libro que te recomienda JuanK, ahí viene explicado con mucho detalle. ¿Qué es lo que no entiendes del programa?

68
C/C++ / Re: Creacion De Menus De Texto.
« en: Viernes 3 de Junio de 2005, 14:51 »
En esta liga a otro foro
http://foro.elhacker.net/index.php/topic,68516.0.html
puedes encontrar el programa, ligeramente modificado por mi, del primer capítulo del libro que te recomienda JuanK, el cual es un sencillo ejemplo de como hacer menús en MS-DOS utilizando manejo directo a la memoria de video (ahí mi nombre de usuario es Juan_Perez)

69
C/C++ / Re: Programa Es C++
« en: Jueves 2 de Junio de 2005, 21:58 »
Lo primero que tienes que hacer es identificar qué va a tener tu "base de datos". Una base de datos generalmente se compone de varios archivos los cuales contienen a las tablas, los índices y otros datos. Como sólo es un ejercicio simple el que quieres hacer entonces con definir un sólo archivo bastaría. Según pones parece que quieres dar de alta unos productos. Supongamos que estos productos tienen una descripción, un código y un costo, entonces primeramente definirías una estrucura así:
Código: Text
  1.  
  2. struct producto {
  3.    char descripcion[80];
  4.    int codigo;
  5.    double costo;
  6. };
  7.  
  8.  
para guardar productos que tengan este formato tienes que crear un archivo. Puedes usar las funciones de archivos de la librería estándar de C suyo encabezado es <stdio.h>. Primero debes de crear un archivo usando la función fopen; para guardar un producto puedes usar la función fwrite; para leer un producto de la base de datos puedes usar la función fread. Al final debes de cerrar el archivo usando la función fclose. Trata de investigar los parámetros que utilizan estas funciones y busca ejemplos de cómo se usan. En internet hay varios lugares donde lo explican, simplemente buscando con el google. Hasta luego y suerte con tu proyecto.

70
C/C++ / Re: Problemas Con La Librería Dir.h En Visual C++
« en: Jueves 2 de Junio de 2005, 09:22 »
No sé cuál función estés utilizando de C, pero si usas el compilador Turbo C, allí si tienen el encabezado <dir.h>. Si buscas en el directorio include que viene en el compilador de Dev C++ también encontrarás este encabezado, pero si lo abres leerás al principio que ese archivo sólo está ahí por compatibilidad con versiones anteriores y te recomiendan que mejor uses el archivo de encabezado <io.h>. Este último si viene en el compilador de Visual C++ (bueno, al menos en la vesrión 6, que es la que uso), y posiblemente venga ahí la o las funciones que uses declaradas en el archivo de encabezado <dir.h>

71
C/C++ / Re: Listas Relacionadas Con Ficheros En C
« en: Miércoles 1 de Junio de 2005, 19:11 »
Bueno, eso sí lo entiendo, pero yo te preguntaba cómo tenías pensado hacerla ¿usando memoria dinámica para crear los elementos en memoria? si va a ser dinámica en memoria ¿por qué preguntabas que no sabias como escribir en un archivo?

72
C/C++ / Re: Listas Relacionadas Con Ficheros En C
« en: Miércoles 1 de Junio de 2005, 17:13 »
No acabo de entenderte bien. Vas a leer toda esa información desde un archivo de texto ¿verdad? Ahora, al leerlos ¿vas a crear dinámicamente en memoria cada elemento que contenga información de la estructura y los vas a enlazar para crear la lista? ¿en qué momento vas a insertar al principio o al final o visualizar la lista por apellido? ¿para que necesitas que escriba en el fichero si todo lo manejas en memoria?

73
C/C++ / Re: Funcion Window(x,y,ancho,alto);
« en: Miércoles 1 de Junio de 2005, 14:37 »
Norax, ¿qué compilador usas? Si usas Dev C++ puedes usar las funciones de consola que proporciona Windows para hacer eso. Si usas los turbo C's de Borland puedes hacerlo tu mismo esa función usando apuntadores directos a memoria.

74
C/C++ / Re: Hay Una Funcion Split En C?
« en: Miércoles 1 de Junio de 2005, 13:46 »
No conozco el lenguaje Python y menos esa función de la que hablas, pero tal como la describes es fácil implementar una versión en C que haga lo mismo. Aquí te paso un pequeño ejemplo de cómo podrías hacerlo usando las funciones strstr que te encuentra una cadena dentro de otra y strncpy que te copia n caracteres de una cadena a otra (sin añadirle el caracter nulo '\0'). La función strstr te regresa un apuntador a la primera subcadena que encontró y el valor nulo en caso contrario. Como no sé que regresa la función split que mencionas en caso de que no encuentre el caracter que le das, pues lo que yo hice fue copiar toda la cadena. En el ejemplo no compruebo errores de desborde de la memoria de los arreglos para no poner más código.
Código: Text
  1.  
  2. #include &#60;stdio.h&#62;
  3. #include &#60;string.h&#62;
  4. #include &#60;stdlib.h&#62;
  5.  
  6. char *split (char *dest, char *orig, char ch);
  7.  
  8. main ()
  9. {
  10.    char cadena[] = &#34;Martin/Luis/Pedro/Pablo&#34;;
  11.    char s[80], *ap = cadena;
  12.    while (1) {
  13.       ap = split (s, ap, '/');
  14.       printf (&#34;%s&#092;n&#34;, s);
  15.       if (ap == NULL)
  16.          break;
  17.    }
  18.    system (&#34;pause&#34;);
  19. }
  20.  
  21. char *split (char *dest, char *orig, char ch)
  22. {
  23.    char *ap, cad2[2] = &#34; &#34;;
  24.    cad2[0] = ch;
  25.    if ((ap = strstr (orig, cad2)) == NULL) {
  26.       strcpy (dest, orig);
  27.       return NULL;
  28.    } else {
  29.       strncpy (dest, orig, ap - orig);
  30.       *(dest + (ap - orig)) = '&#092;0';
  31.       return ap + 1;
  32.    }
  33. }
  34.  
  35.  

75
C/C++ / Re: Assembly
« en: Miércoles 1 de Junio de 2005, 02:52 »
Si te interesa, y lees literatura en inglés de computación, te puedo poner aquí lo que al respecto viene en el MSDN 6 de Microsoft. Te muestro la primera página
------------------------------------
Citar
Assembler (Inline): Overview
Home |  How Do I |  Details

Assembly language serves many purposes, such as improving program speed, reducing memory needs, and controlling hardware. You can use the inline assembler to embed assembly-language instructions directly in your C and C++ source programs without extra assembly and link steps. The inline assembler is built into the compiler — you don't need a separate assembler such as the Microsoft Macro Assembler (MASM).

Note   Programs with inline assembler code are not fully portable to other hardware platforms. If you are designing for portability, avoid using inline assembler.

What do you want to know more about?
Inline assembler


The __asm keyword


C or C++ in __asm blocks


Registers


Jumps to labels


C function calls from an __asm block


C++ function calls from an __asm block


__asm blocks as C macros


Optimizing inline assembly code


Páginas: 1 2 [3] 4 5