Menú

Mostrar Mensajes

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

Mostrar Mensajes Menú

Mensajes - rir3760

#271
Programación C/C++ / Re: Problema con registros
5 Septiembre 2014, 17:35 PM
Cita de: wiD^ en  4 Septiembre 2014, 22:50 PMno 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:
fgets((*clientes).apellido, 30, *db);
printf("%s\n", (*clientes).nombre);

A:
fgets(clientes->apellido, 30, *db);
printf("%s\n", clientes->nombre);


Cita de: wiD^ en  4 Septiembre 2014, 22:50 PMNo 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).

Cita de: wiD^ en  4 Septiembre 2014, 22:50 PMy 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
Cita de: ++c en  4 Septiembre 2014, 23:08 PMMirar 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:
/* 2) Tratar de leer el numero indicado */
regs_leidos = fread(persona, sizeof persona[0], regs_a_leer, fichero);


Cita de: ++c en  4 Septiembre 2014, 23:08 PM2. 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.

Cita de: ++c en  4 Septiembre 2014, 23:08 PM3. 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.

Cita de: ++c en  4 Septiembre 2014, 23:08 PMPdata: 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:
while (fread(&persona,sizeof(persona),1,fichero) == 1){
   printf("\nIntroduzca numero de persona a visualizar: ");
   fgets(temporal,19,stdin);
   sscanf(temporal,"%d",&numero);
   
   printf("\nNombre: %s",persona[numero].nombre);
   printf("\nCiudad: %s\n",persona[numero].ciudad);
   printf("Edad: %d",persona[numero].edad);
}


Un saludo
#273
Cita de: ++c en  3 Septiembre 2014, 19:04 PMestoy 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í:
if ((fichero = fopen(name, "rb")) == NULL){
   /* Manejo de error */
}else {
   char aux[128];
   int regs_a_leer;
   int regs_leidos;
   
   /* 1) Obtener el numero de registros a leer */
   puts("Numero de personas a visualizar:");
   fgets(aux, sizeof aux, stdin);
   sscanf(aux, "%d", &regs_a_leer);
   
   /* 2) Tratar de leer el numero indicado */
   regs_leidos = fread(persona, sizeof persona[0], regs_a_leer, fichero);
   
   /* 3) Imprimir los registros leidos */
   for (i = 0; i < regs_leidos; i++){
      printf("Registro No %d\n", i + 1);
     
      printf("Nombre: %s\n", persona[i].nombre);
      printf("Ciudad: %s\n", persona[i].ciudad);
      printf("Edad: %d\n", persona[i].edad);
   }
   
   fclose(fichero);
}


Un saludo
#274
Cita de: kutcher en  3 Septiembre 2014, 19:56 PMSolo 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):
test[i] = '\0';
puts(test);


Un saludo
#275
Programación C/C++ / Re: Problema con registros
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":
fgets((*clientes).apellido, 30, *db); /* Leemos el apellido    */
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:
while (feof(*db) == 0){
   fgets((*clientes).apellido, 30, *db);     /* 1 */
   printf("%s\n", (*clientes).nombre);
   
   fgets((*clientes).apellido, 30, *db);     /* 2 */
   printf("%s\n", (*clientes).apellido);
   
   fscanf(*db, "%d", &(*clientes).telefono); /* 3 */
   printf("%d\n", (*clientes).telefono);
   
   fscanf(*db, "%d", &(*clientes).edad);     /* 4 */
   printf("%d\n", (*clientes).edad);
}


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:
while (feof(*db) == 0){
   fgets((*clientes).apellido, 30, *db);
   printf("%s\n", (*clientes).nombre);
   
   /* ... */
   
   fscanf(*db, "%d", &(*clientes).edad);
   printf("%d\n", (*clientes).edad);
   
   {
      int ch;
     
      while ((ch = fgetc(*db)) != EOF && ch != '\n')
         ;
   }
}


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
Cita de: LauraD en  4 Septiembre 2014, 02:59 AMTengo 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:
for (i = 1; i <= num; i++)
   if (Num1 % i == 0 && Num2 % i == 0)
      ...

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
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:
void bruteforce(int inc, int fin, char *rotation)
{
   int i, j, len = strlen(rotation);
   long int r, end, c;
   char test[200];
   
   end = pow(len, inc);
   for(j = inc; j < fin + 1; j++){
      for (r = 0; r != end; r++){
         c = r;
         for (i = 0; i < j; i++){
            test[i] = rotation[c % len];
            c = c / len;
         }
         printf("%.*s\n", i, test);
      }
     
      end *= len;
   }
}

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
Cita de: NOB2014 en  3 Septiembre 2014, 16:17 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
Cita de: eferion en  3 Septiembre 2014, 15:02 PMAdemás, te complicas demasiado la forma de recorrer la cadena:

Código (cpp) [Seleccionar]
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 (cpp) [Seleccionar]
bool palindromo(char const *str)
{
   size_t i;
   size_t j = strlen(str) - 1;
   
   for (i = 0; i < j && str[i] == str[j]; i++, j--)
      ;
   
   return i >= j;
}


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
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 (cpp) [Seleccionar]
while (getline(is, line))
   v.push_back(line);


Un saludo