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

 

 


Tema destacado: Curso de javascript por TickTack


  Mostrar Mensajes
Páginas: 1 ... 13 14 15 16 17 18 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 ... 160
271  Programación / Programación C/C++ / Re: Problema con registros en: 5 Septiembre 2014, 17:35 pm
no entendí lo siguiente:

* En ambas funciones utilizas la notación "(*variable).campo" cuando puedes acortar evitando los paréntesis con "variable->campo".

No entiendo a que te refieres con: variable->campo
En C "->" es un operador y se utiliza para en base a un puntero a estructura acceder al campo indicado. Donde sea que utilices "(*puntero).nombre_del_campo" puedes sustituirlo por "puntero->nombre_del_campo" con el mismo resultado.

Tomando tu programa como ejemplo puedes cambiar esta parte:
Código
  1. fgets((*clientes).apellido, 30, *db);
  2. printf("%s\n", (*clientes).nombre);
A:
Código
  1. fgets(clientes->apellido, 30, *db);
  2. printf("%s\n", clientes->nombre);

No entiendo que hace el segundo while
Ese bucle lee un carácter y lo descarta (lee otro) hasta encontrarse con uno que sea igual a EOF (indica error) o '\n' (indica el final de la linea). El objetivo de ello es descartar el resto de la linea ya que fscanf no lee por linea (fgets si y ahí empiezan los problemas que ya comente).

y cuando entraría adentro de esas llaves
Siempre. Puedes tener un bloque delimitado por llaves en cualquier lugar donde una sentencia sea valida y no hay problema, el objetivo de utilizar un bloque es evitar un conflicto de nombres si, por alguna razón, ya existe una variable con el nombre "ch".

Un saludo
272  Programación / Programación C/C++ / Re: Escritura y lectura de archivos binarios en: 5 Septiembre 2014, 04:14 am
Mirar lo que quiero que haga el programa en la lectura:

1. Lea el fichero.
Ya que en el programa declaras un array de N elementos solo tienes que utilizar la función fread para tratar de leer ese numero. Ya que se puede leer un numero menor almacenas el valor de retorno de la función en una variable (es el numero de elementos leídos). Eso ya lo explique en mi mensaje anterior:
Código
  1. /* 2) Tratar de leer el numero indicado */
  2. regs_leidos = fread(persona, sizeof persona[0], regs_a_leer, fichero);

2. Que pregunte al usuario por el nº de registro que desea visualizar.
Solo tienes que utilizar la función scanf para obtener el indice del elemento en el array: 0 .. regs_leidos - 1.

3. El programa mostrará los datos correspondientes a ese usuario.
Imprimes el valor de los campos del elemento en cuestión, de nuevo eso ya lo tienes.

Pdata: se que no se ve de muy buena forma el uso de !feof por algunos programadores.
El problema con feof es que usualmente es innecesaria ya que se puede utilizar directamente el valor de retorno de la función utilizada.

Por ejemplo en tu programa se debe duplicar la sentencia de lectura para que el bucle funcione correctamente (con feof) cuando utilizando el valor de retorno de fread te olvidas de feof y la duplicación:
Código
  1. while (fread(&persona,sizeof(persona),1,fichero) == 1){
  2.   printf("\nIntroduzca numero de persona a visualizar: ");
  3.   fgets(temporal,19,stdin);
  4.   sscanf(temporal,"%d",&numero);
  5.  
  6.   printf("\nNombre: %s",persona[numero].nombre);
  7.   printf("\nCiudad: %s\n",persona[numero].ciudad);
  8.   printf("Edad: %d",persona[numero].edad);
  9. }

Un saludo
273  Programación / Programación C/C++ / Re: Escritura y lectura de archivos binarios en: 4 Septiembre 2014, 17:26 pm
estoy tratando de hacer un código de archivo binario con array de estructuras pero no encuentro como hallar adecuadamente la lectura de los registros que introduzco con fread.
Como ya te comento eferion el programa tiene bastantes errores, si no tienes un curso o libro de calidad debes conseguir uno, recomendaciones sobre ellos las puedes revisar mediante el motor de búsqueda de los foros.

Diría que el error principal es lógico (imprimir el registro y solo después de ello leerlo) pero debido a la cantidad de errores es mejor rescribir esa parte desde cero. Los pasos son:

1) Pides el numero de registros al usuario.
2) Llamas a fread tratando de leer el numero indicado (pueden ser menos).
3) Utilizas un bucle para imprimir cada registro leído.

Mas o menos así:
Código
  1. if ((fichero = fopen(name, "rb")) == NULL){
  2.   /* Manejo de error */
  3. }else {
  4.   char aux[128];
  5.   int regs_a_leer;
  6.   int regs_leidos;
  7.  
  8.   /* 1) Obtener el numero de registros a leer */
  9.   puts("Numero de personas a visualizar:");
  10.   fgets(aux, sizeof aux, stdin);
  11.   sscanf(aux, "%d", &regs_a_leer);
  12.  
  13.   /* 2) Tratar de leer el numero indicado */
  14.   regs_leidos = fread(persona, sizeof persona[0], regs_a_leer, fichero);
  15.  
  16.   /* 3) Imprimir los registros leidos */
  17.   for (i = 0; i < regs_leidos; i++){
  18.      printf("Registro No %d\n", i + 1);
  19.  
  20.      printf("Nombre: %s\n", persona[i].nombre);
  21.      printf("Ciudad: %s\n", persona[i].ciudad);
  22.      printf("Edad: %d\n", persona[i].edad);
  23.   }
  24.  
  25.   fclose(fichero);
  26. }

Un saludo
274  Programación / Programación C/C++ / Re: Optimización de algoritmo de fuerza bruta en: 4 Septiembre 2014, 05:27 am
Solo le cambie lo del printf ya que considero que es mas lento que puts
En ese caso debes agregar manualmente el carácter '\0' justo antes de la llamada a función (esa es la ventaja de printf):
Código
  1. test[i] = '\0';
  2. puts(test);

Un saludo
275  Programación / Programación C/C++ / Re: Problema con registros en: 4 Septiembre 2014, 05:19 am
Si no tienes un curso o libro de calidad deberías conseguir uno, para recomendaciones basta con utilizar el motor de búsqueda de los foros.

Deficiencias en el fragmento hay bastantes:

* Falta consistencia: una función cierra el archivo, la otra lo abre y cierra. Bien ambas funciones operan sobre el archivo (lo abren y cierran) o ambas solo realizan la operación en turno.

* No es necesario emular el paso por referencia.

* En la función "DarDeAlta" la ultima sentencia esta de mas (las funciones terminan con su llave de cierre), hay que cambiar la función "Seguir" para utilizar su valor de retorno y una vez hecho lo anterior se cambia el bucle por uno do ... while eliminando de paso la variable local "a".

* En la función "MostrarClientes" los dos últimos parámetros no son necesarios: "n" no es utilizado en la función mientras que lo primero que haces con "db" es sobrescribir su valor, este ultimo se debe cambiar por una variable local.

* Hay un error lógico en la función "MostrarClientes":
Código
  1. fgets((*clientes).apellido, 30, *db); /* Leemos el apellido    */
  2. printf("%s\n", (*clientes).nombre);   /* Imprimimos el nombre  */

* En ambas funciones utilizas la notación "(*variable).campo" cuando puedes acortar evitando los paréntesis con "variable->campo".

* El error que mencionas se debe al uso intercalado de fgets y fscanf en la función "MostrarClientes". Para explicarlo mejor etiquetamos los pasos en cada iteracion:
Código
  1. while (feof(*db) == 0){
  2.   fgets((*clientes).apellido, 30, *db);     /* 1 */
  3.   printf("%s\n", (*clientes).nombre);
  4.  
  5.   fgets((*clientes).apellido, 30, *db);     /* 2 */
  6.   printf("%s\n", (*clientes).apellido);
  7.  
  8.   fscanf(*db, "%d", &(*clientes).telefono); /* 3 */
  9.   printf("%d\n", (*clientes).telefono);
  10.  
  11.   fscanf(*db, "%d", &(*clientes).edad);     /* 4 */
  12.   printf("%d\n", (*clientes).edad);
  13. }

Primera iteración:

1 fgets lee el nombre (ya se menciono que hay un error lógico).
2 fgets lee el apellido.
3 fscanf lee el telefono, deja el ultimo carácter invalido (el avance de linea) en el bufer correspondiente.
3 fscanf lee la edad, deja el ultimo carácter invalido (el avance de linea) en el bufer correspondiente.

Segunda iteración:

1 fgets lee el '\n' como una linea en blanco y se almacena esta en el nombre.
2 fgets lee el nombre y lo almacena en el apellido.
3 fscanf falla al tratar de leer el telefono del apellido.
4 fscanf falla al tratar de leer la edad del apellido.

Tercera iteración

1 fgets lee el nombre (apellido del registro anterior)
2 fgets lee el apellido (telefono del registro anterior)
etc.

Para solucionarlo se tienen dos opciones:

A) Leer todas las lineas del archivo con fgets, de ser necesario (por ejemplo en este caso con el teléfono y la edad) se utiliza un array de caracteres auxiliar y la función sscanf para extraer el valor.

B) Justo después de la llamada a fscanf y antes de la llamada a fgets se descarta el resto de la linea con un bucle, tomando tu caso como ejemplo:
Código
  1. while (feof(*db) == 0){
  2.   fgets((*clientes).apellido, 30, *db);
  3.   printf("%s\n", (*clientes).nombre);
  4.  
  5.   /* ... */
  6.  
  7.   fscanf(*db, "%d", &(*clientes).edad);
  8.   printf("%d\n", (*clientes).edad);
  9.  
  10.   {
  11.      int ch;
  12.  
  13.      while ((ch = fgetc(*db)) != EOF && ch != '\n')
  14.         ;
  15.   }
  16. }

Por ultimo en la función "MostrarClientes" se debe evitar el uso de la función "feof" ya que esto resultara en un iteración de mas, en su lugar hay que verificar el valor de retorno de las funciones fgets y fscanf.

Un saludo
276  Programación / Programación C/C++ / Re: Programa divisores en C++, Urgente!! en: 4 Septiembre 2014, 04:29 am
Tengo que elaborar un algoritmo en el que se ingresen 2 números, deben indicarse cuantos y cuales son sus divisores y cuantos y cuales son los divisores que tienen en comun estos dos numeros
Solo necesitas agregar un tercer bucle donde verifiques si el residuo de la división de ambos números es cero:
Código
  1. for (i = 1; i <= num; i++)
  2.   if (Num1 % i == 0 && Num2 % i == 0)
  3.      ...
Donde (por eficiencia) "num" es el menor de los dos números (puedes utilizar el mayor obteniendo los resultados correctos pero con iteraciones innecesarias).

----

Y por favor cuando abras un tema evita títulos como "Urgente", "Auxilio", etc.

Un saludo
277  Programación / Programación C/C++ / Re: Optimización de algoritmo de fuerza bruta en: 3 Septiembre 2014, 19:29 pm
Primero las recomendaciones:

1) Las conversiones explicitas al tipo long int no son necesarias ya que se realizan de forma automática, por ello hay que eliminarlas.

2) Los dos bucles while se pueden sustituir por bucles for para compactar el código fuente.

3) Puedes utilizar una sola vez la función pow justo antes del bucle externo, la actualización del valor de la variable "end" se debe realizar justo al final del mentado bucle.

Con los cambios:
Código
  1. void bruteforce(int inc, int fin, char *rotation)
  2. {
  3.   int i, j, len = strlen(rotation);
  4.   long int r, end, c;
  5.   char test[200];
  6.  
  7.   end = pow(len, inc);
  8.   for(j = inc; j < fin + 1; j++){
  9.      for (r = 0; r != end; r++){
  10.         c = r;
  11.         for (i = 0; i < j; i++){
  12.            test[i] = rotation[c % len];
  13.            c = c / len;
  14.         }
  15.         printf("%.*s\n", i, test);
  16.      }
  17.  
  18.      end *= len;
  19.   }
  20. }
Como no publicas el programa completo te toca a ti verificar que funcione correctamente (ya nos avisas si hubo algún resbalón).

----

Un ultimo comentario: si se trata de una solución de fuerza bruta la prioridad debe ser la claridad del código fuente, si esta fuera la eficiencia lo mejor es simplemente ... cambiar de algoritmo.

Un saludo
278  Programación / Programación C/C++ / Re: Medir el tiempo de una rutina en lenguaje C. en: 3 Septiembre 2014, 18:57 pm
¿alguien me puede decir si se puede lograr lo mismo con con un programa en C puro?
No ya que al utilizar solo las facilidades de la biblioteca estándar de C (difftime, struct tm, clock) se garantiza una resolución en segundos, nada mas.

Para el calculo exacto lo mejor es utilizar extensiones (como es el caso con tu ejemplo usando la Win32 API).

Un saludo
279  Programación / Programación C/C++ / Re: Programa para detectar palindromos en: 3 Septiembre 2014, 18:06 pm
Además, te complicas demasiado la forma de recorrer la cadena:

Código
  1. int j = sizeof(cadena)/sizeof(cadena[0]);

sizeof(cadena) te va a dar 100
Ya que todo parámetro declarado como "T [N]" se procesa en realidad como "T *" el resultado de "sizeof(cadena)" sera igual a "sizeof(char *)". Por supuesto no deja de ser un error y hay que cambiar la aproximación a, como sugieres, el uso de la función strlen.

En el caso de cadenas "a la C" una aproximación en la misma linea mas propia de C que de C++ es:
Código
  1. bool palindromo(char const *str)
  2. {
  3.   size_t i;
  4.   size_t j = strlen(str) - 1;
  5.  
  6.   for (i = 0; i < j && str[i] == str[j]; i++, j--)
  7.      ;
  8.  
  9.   return i >= j;
  10. }

Un detalle a tener en cuenta es que no hay protección en caso de una cadena vacía (solo el cero), en ese caso daría resultados incorrectos.

Un saludo
280  Programación / Programación C/C++ / Re: duda para un programita en: 30 Agosto 2014, 18:04 pm
En la mayoria de los casos (por ejemplo este) se puede evitar el uso de la funcion feof, en su lugar se verifica el resultado de la funcion utilizada:
Código
  1. while (getline(is, line))
  2.   v.push_back(line);

Un saludo
Páginas: 1 ... 13 14 15 16 17 18 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 ... 160
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines