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

 

 


Tema destacado: Security Series.XSS. [Cross Site Scripting]


  Mostrar Mensajes
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 102
11  Programación / Programación C/C++ / Re: Extraer palabras de un texto leido en un archivo (en C) en: 22 Noviembre 2022, 18:56 pm

Lo que sí se me volvio a romper en la parte donde reemplacé sizeof() por strlen() tanto en fwrite() como en fread(), pero voy a ver bien qué puede ser. (Te referias de usar: fwrite(&texto, sizeof(char)* strlen(texto), 1, pfile) ) ?
Si te fijas bien en el código, en fread() no utilicé strlen(). Por qué? Porque strlen(texto) = 0 ya que está vacío en ese momento.
Cuando lees del archivo no sabes cuántos bytes tienes que leer por eso se intenta leer el máximo disponible: TAM_MAX.

Por otro lado, no hace falta multiplicar strlen(texto) por sizeof(char). Sí sería la forma correcta pero como un char ocupa 1 byte, sizeof(char) = 1.
Por eso se puede omitir esa multiplicación y hacer el código un poco más sencillo. Si la pones no está mal, estaría bien porque si el tamaño de un char cambiase seguiría funcionando bien.


Lo de la parte 3 supongo que te refieres a la funcion archivoToDic()?
En esa parte también inicialize el arreglo
Código
  1. aux[20] = { 0 };
que este arreglo se utilizaba para guardar una palabra del texto general.
Sí, con la parte 3 me refería a la última función, que intentarás sacarla tú solo aplicando lo visto en las otras funciones.
Si no lo consigues vuelve a dejar la parte que te da problemas con los avances y así poder echarle un ojo  :o
12  Programación / Programación C/C++ / Re: Extraer palabras de un texto leido en un archivo (en C) en: 21 Noviembre 2022, 18:07 pm
Tras un par de pruebas, todo parece indicar que a partir de palabras con 8 caracteres, se muestra basura al final.
De todas formas, aunque en alguna ocasión no se vea basura, no significa que el funcionamiento sea correcto. Por lo tanto, vamos a verlo...

Respondiendo a tu pregunta final: Se podría usar memoria dinámica? Sí. Es necesario? No. Ahora lo vas a ver...  :o


Parte 1: Crear fichero (a partir de aquí vamos a suponer que introduzco "hola")

Aquí ya podemos hacer varias mejoras:
  • Por un lado, vamos a reemplazar la función gets() por fgets(). Es la versión "segura" de gets() para evitar problemas si nos pasamos del tamaño máximo de la variable: fgets(texto, TAM_MAX, stdin)
    Con esto le estamos diciendo: guarda en <texto> los primeros TAM_MAX-1 (como mucho) caracteres obtenidos de stdin (entrada estándar). Si hay menos, guardará los que haya y si hay más, los ignorará y los dejará en el buffer (he aquí la magia mejorada en contra de gets())
    • Y por qué guarda TAM_MAX-1 caracteres si la capacidad es TAM_MAX? Porque al final siempre va a incluir "a terminating null character" (\0) que indica el fin de la cadena. En C siempre se indica el fin de una cadena de chars con un '\0'. Se nos habrá guardado en <texto> = {'h', 'o', 'l', 'a', '\0', ...}
    • fgets() almacena el carácter '\n' al pulsar Enter. Antes te engañé, en 'texto' se guardó = {'h', 'o', 'l', 'a', '\n', '\0', ...} Esto se puede solucionar de la siguiente manera:
Código
  1. fgets(texto, SIZE, stdin);
  2. // En mi opinion, este fragmento deberia ir practicamente siempre despues de un fgets() usando stdin como entrada
  3. if(texto[strlen(texto) - 1] == '\n')  // Si el ultimo caracter guardado (strlen devuelve el numero de chars hasta encontrar un '\0') es un Enter, significa que no queda nada en el buffer
  4.    texto[strlen(texto) - 1] = '\0';  // Adelanta el '\0' y sobreescribe el Enter (da igual todo lo que haya despues)
  5. else                                  // Y si no es Enter, significa que nos hemos pasado de longitud y han quedado cosas en el buffer, entre ellas el Enter
  6.    while(getchar() != '\n');         // entonces consumimos el buffer para dejarlo limpio y evitar errores futuros.
  7.  


  • Por otro lado, cuando escribimos el contenido en el fichero, tenemos que indicar el número de bytes que queremos escribir.
    En lugar de indicar sizeof(texto) que escribiría 1000 bytes en el fichero, vamos a indicar strlen(texto) para escribir sólo 4. Ves, no hacía falta usar memoria dinámica  ;-)
    Escribiendo strlen(texto) estaremos escribiendo EXACTAMENTE lo que el usuario introdujo, ni un carácter más ni uno menos. (Puedes usar un editor hexadecimal o un editor que muestre caracteres no imprimibles para ver el contenido exacto del fichero)
    Ahora tenemos esto:
Código
  1. void crearArchivo()
  2. {
  3.    FILE* pfile = fopen(ARCH0, "wb");
  4.    char texto[TAM_MAX];
  5.  
  6.    if( pfile ) {
  7.        printf("\nIngrese el texto:\n");
  8.        fgets(texto, TAM_MAX, stdin);
  9.  
  10.        if(texto[strlen(texto) - 1] == '\n') texto[strlen(texto) - 1] = '\0';
  11.        else while(getchar() != '\n');
  12.  
  13.        fwrite(texto, strlen(texto), 1, pfile);
  14.        fclose(pfile);
  15.    }
  16. }


Parte 2: Mostrar fichero

Aquí tenemos que leer el contenido del fichero. Lo importante es que no se nos cuele basura después del texto que hay dentro del fichero.
La solución más sencilla es inicializar el array de chars con 0s. 0 es el valor numérico del carácter nulo (0 = '\0')
De esta manera, con fread leeremos el contenido del fichero y el resto de espacio que sobre en el array ya estará rellenada con 0s por lo que no mostraremos ninguna basura.
Código
  1. char texto[TAM_MAX] = {0};
  2. if(pfile) {
  3.    fread(texto, TAM_MAX, 1, pfile);
  4.    puts(texto);
  5.    fclose(pfile);
  6. }


Parte 3... Está es para ti que sino menudo aburrimiento si no puedes probarlo tú mismo  :-X
13  Programación / Programación C/C++ / Re: menu de opciones con clases en: 17 Noviembre 2022, 18:47 pm
Yo venía todo dispuesto a echar un vistazo al código y... oh sorpresa, ha desaparecido  :o

Tendrás que ser un poco más específico en lo que quieres hacer.
A qué te referías con que "se queda atascado"? Muestra algo? No muestra nada?...
14  Programación / Programación C/C++ / Re: error expected unqualified-id before '+ ' token en: 12 Noviembre 2022, 01:11 am
No se puede ver el código.
En vez de intentar subir una imagen o links externos, utiliza las etiquetas de Código GeSHi para añadir tu código al mensaje de forma que quede tal que así
Código
  1. #include <iostream>
  2.  
  3. int main() {
  4.    ...
  5. }

De todas formas, por lo que indicas al final, no sé cuál es el propósito de esa línea pero esa expresión no es válida...  :huh:
15  Programación / Programación General / Re: Guardar lineas de un archivo java en un vector en: 5 Noviembre 2022, 13:23 pm
Echando un vistazo a la documentación de Java sobre el método BufferedReader.mark(int), se puede ver que el parámetro indica el número de caracteres que se pueden leer del stream mientras se sigue manteniendo la marca. Es decir, usando 'lines.mark(1)' se mantendrá la marca hasta que se lea el segundo carácter...

Para que funcione, el número no puede ser menor al número de caracteres que tiene el fichero ya que tu propósito es leerlo entero.

Creo que hay mejores opciones como:
  • Utilizar un ArrayList<String> para poder añadir líneas de forma dinámica sin tener que calcular antes el número de líneas.
  • Utilizar Files.readAllLines() que directamente devuelve un ArrayList con todas las líneas del fichero.

    Si necesitas guardar las líneas en un String[], siempre puedes convertir el ArrayList<String> a String[]
16  Programación / Programación C/C++ / Re: Pila en C++ en: 1 Noviembre 2022, 08:02 am
En las funciones pop() y liberar() estás creando un puntero nuevo llamado p_aux en vez de usar el original que está declarado globalmente.
Esto es lo que está produciendo errores de acceso a memoria... :rolleyes:
17  Programación / Programación C/C++ / Re: Duda ejercicio fecha en: 28 Octubre 2022, 19:26 pm
Ah claro, en los meses en donde voy a dar utilidad al array.
Solo una última pregunta, yo para dia mes y año he creado variables de tipo int. ¿Tendrá espacio suficiente?
Hmm no sé no sé... Igual usando variables de tipo int estás un poco apurado...  :rolleyes:
Piensa que una variable de tipo int suelen ser 32 bits por lo que tan solo podrías llegar hasta el número: 2^(32-1) -1 = 2147483647 días (incluido)
Y si no lo he calculado mal ese número de días corresponde al: 03/11/5883517. Como introduzcas un día de diciembre de ese año, tu progama explotará...  :silbar:
18  Programación / Programación C/C++ / Re: Duda ejercicio fecha en: 27 Octubre 2022, 19:08 pm
El enfoque de K-YreX me parece el correcto en principio, pero creo que la cosa es un pelín más complicada y hay que darle una vuellta de tuerca más.

Habría pues que reacomodar el algoritmo (y el dato de partida de nº de días de Febrero) para tenerlo en cuenta. A este respecto comentar que, además, no solo son bisiestos cada 4 años, los divisibles entre 4 (división por 4 con resto 0), sino que el sistema tiene más correcciones de manera que no todos los que cumplen el requisito de ser divisibles por 4 exactamente son automáticamente bisiestos; por ejemplo 1900 no fue bisiesto a pesar de ser divisble exactamente por 4 (cociente 475 - resto 0). Hay correcciones adicionales al sistema del calendario.
Efectivamente, tal y como dices para hacerlo más correcto habría que tener en cuenta los años bisiestos. Sin embargo, viendo que es un ejercicio típico de introducción a la programación, cuando quieren que tengas en cuenta los años bisiestos, te lo suelen indicar (por experiencia).
Es por eso que opté por no mencionarlo y así no complicarlo más. Siempre queda la posibilidad de mejorarlo a futuro... :rolleyes: :rolleyes:

Por otro lado, ciertamente los años bisiestos no son aquellos divisibles por 4. El cálculo es un pelín más complejo:
Código:
esBisiesto = ( año % 4 == 0 && (año % 100 != 0 || año % 400 == 0) ) 



Hola, creo que así te respondo a este mensaje, desconozco si hay otra forma de hacerlo mejor, pero no entiendo la parte en la que pones "diasDeMesesCompletosHasta(mes-1).
Sí, con eso ya haces referencia al mensaje.

Supongamos que no hay años bisiestos y queremos calcular la cantidad de días totales que han transcurrido hasta el día de hoy (27/10/2022):
1. Calculamos los días de los años que han pasado completos (aquí tuve un error y se nos ha colado a todos  :P, lo corregiré en el post original cuando termine con este mensaje): (año - 1) * 365 = 2021 * 365 = 737665 días
¿Por qué (año-1)? Porque el año 2022 no ha terminado. Si multiplicásemos: 2022 * 365 nos daría la cantidad de días que han pasado hasta terminar el 2022 y eso no nos sirve... El año actual hay que ir desgranándolo en meses completos y luego en días sueltos.

2. Calculamos los días de los meses que han pasado completos: dias_mes1 + dias_mes2 + dias_mes3 + ... + dias_(mes-1) = 31 (enero) + 28 (febrero) + 31 (marzo) + 30 (abril) + 31 (mayo) + 30 (junio) + 31 (julio) + 31 (agosto) + 30 (septiembre) = 273 días
Misma pregunta: ¿por qué hasta (mes-1)? Misma respuesta  :xD: Porque si calculásemos hasta el mes actual incluido, estaríamos calculando los días totales suponiendo que el mes actual (octubre) ha terminado y no es así.
En este paso es donde te será de gran utilidad tener el array con los días que tiene cada mes. ¿Por qué? Sencillo, ¿hasta qué índice del array tienes que recorrer mientras los vas sumando...?  :silbar: :silbar:
Ya hemos degranado los meses completos, ahora sólo quedan los días sueltos, es decir, ¿cuántos días de octubre han transcurrido ya?

3. Calculamos los días transcurridos del mes actual: Simple... 27 días

4. Sumamos todas las cantidades: 737665 días + 273 días + 27 días = 737965 días totales
19  Programación / Programación C/C++ / Re: Duda ejercicio fecha en: 26 Octubre 2022, 22:01 pm
Tú mismo lo has dicho:
Citar
Porque en algún sitio tendré que especificar los meses que tienen 31 días, 30 o 28, ¿no?

Puedes hacerlo usando el mismo array que tienes en tu código original o sin él (calculando los días que tiene cada mes con un switch-case)
Yo te recomiendo que sigas utilizando el array pues quedará más limpio a la hora de calcular los diasTotales y de recalcular la fecha final.
20  Programación / Programación C/C++ / Re: Duda ejercicio fecha en: 26 Octubre 2022, 21:05 pm
Plantear el problema de la manera que lo has hecho te va a dar muchos quebraderos de cabeza.
¿Qué pasa si restas más de 2 meses? ¿Y más de 3?

El planteamiento que te propongo es:
1. Pides una fecha
2. Calculas esa fecha en días totales
Código:
diasTotales = (año-1) * diasQueTiene1Año + diasDeMesesCompletosHasta(mes-1) + dia
3. Restas los días que te indiquen
Código:
diasTotales -= n
4. Conviertes la cantidad de días totales que te quedan en una fecha
Código:
año = diasTotales / 365
diasTotales %= 365
...

Te he dejado por ahí un par de pistas. Dale una vuelta y a ver si lo consigues  :-X

Si te quedas en algún punto, puedes volver a comentar con tu nuevo código pero esta vez utiliza las etiquetas de Código GeSHi:
Cuando tengas el código copiado, lo seleccionas y en el desplegable que dice "Código GeSHi" seleccionas el lenguaje C. Debería quedarte tal y como se ve ahora el código de tu primer mensaje

EDIT:
Corregido un pequeño error en el cálculo de días totales...  :-X
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 102
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines