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

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


  Mostrar Mensajes
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1  Programación / Programación C/C++ / Re: Lectura teclado en: 4 Enero 2022, 16:34 pm
Como ya te dijeron, no hay forma estándar ni portable. O usas bibliotecas multiplataforma, como las que ya te mencionaron, o recurres a funciones específicas de cada sistema operativo. En Windows, la forma más sencilla y parecida a lo que se hace en Pascal es usar las funciones _kbhit() y _getch() (debes incluir "conio.h"). La primera verifica si hay una tecla presionada, y la segunda lee una tecla (que puede ser una de las "especiales", como Esc, las flechas, etc) sin esperar a que se presione Enter. Obviamente esto es muy distinto a lo que hace getchar().

No hay nada de malo en usar estas funciones cuando es necesario. Te lo digo porque a veces se critica de forma exagerada su uso. Sí, no son estándar de C o C++, pero es que no hay manera estándar de hacer lo que quieres, así que se justifica utilizarlas. Y conio.h es parte del runtime de C de Microsoft desde hace mucho, por lo que todo compilador para Windows que se precie la incluye, como es el caso de MinGW y, obviamente, VC++:

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/getch-getwch?view=msvc-170
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/kbhit?view=msvc-170
2  Programación / Programación C/C++ / Re: Programacion en C en: 4 Enero 2022, 00:41 am
Eso indica que no encuentra el archivo. ¿Seguro que se llama "hijo" y no "hijo.o" o algo así? Porque al parecer el ejecutable principal se llama "padre.o" (que realmente no debería tener esa extensión, pero eso es otro tema). De cualquier forma, puedes probar abriendo una terminal y desde el mismo directorio desde el que ejecutas padre, ejecuta el comando ./hijo, y ve si funciona.

En cuanto a argv, me refería a este for:

Código
  1. for(i=1; i<NUM_HIJOS; i++){

Como NUM_HIJOS vale 10, i tomará valores desde 1 a 9. Si al programa le pasas menos de 9 argumentos, llega un punto en el que con argv[ i ] estarás intentando ir más allá del final de argv. Nota también que el hecho de iniciar el for desde 1 significa que realmente estás limitando el número máximo de hijos a 9, no a 10, aunque creo que es un detalle sin mucha importancia.

Veo que luego vas a tener que imprimir lo que read lea. Algo que causa muchos problemas es olvidar que el búfer que te da esa función no necesariamente contiene caracter nulo '\0', así que es importante verificar el valor que te devuelve (el número de bytes leídos) y, o cierras manualmente la cadena, o le indicas a printf el número de caracteres a imprimir. Por ejemplo:

Código
  1. if ((num_caracteres = read(fd[0], buffer, MAXBUFFER)) > 0)
  2. printf("%.*s", num_caracteres, buffer);

Y te reitero, los hijos deberían cerrar fd[0], y, después del dup, fd[1]. Aunque en este caso no te dará problemas, es una mala práctica no hacerlo. Caso completamente distinto al del último exit de ese case 0, que, como te dije en el mensaje anterior, es redundante (aunque tampoco hace ningún mal). Al escribir mi primera respuesta, me enfoqué en los problemas con los pipes y fork y ni siquiera me fijé en que los hijos ejecutaban execl. Obviamente, al llamar a las funciones exec*, sólo es necesario finalizar la ejecución en caso de error, lo cual ya haces.
3  Programación / Programación C/C++ / Re: Programacion en C en: 3 Enero 2022, 16:26 pm
Ese mensaje en tu programa indica que falló execl. Asegúrate de que el archivo "hijo" exista en el mismo directorio que "padre", y que sea ejecutable. Puedes ver más detalles sobre el error si después del fprintf que muestra "Error en la ejecucion del proceso hijo\n", pones:

Código
  1. perror("execl");

Y te digo otra vez, revisa bien el código y lee los apuntes o manuales que tengas, porque todavía hay más errores. Por ejemplo, tu read está mal, ya que el segundo parámetro debería ser una cadena de caracteres. Y a execl le estás pasando argv[ i ]: tal y como tienes el for, eso es incorrecto. Revísalo bien y verás por qué.

Los procesos hijos deberían terminar con _exit o exit, no con return; no sé por qué cambiaste eso. De cualquier forma forma, esa última línea del case 0 no debería retornar EXIT_FAILURE; eso es sólo cuando se finaliza con error. Y ahora que lo vuelvo a ver, estrictamente hablando, en tu programa no necesitarías ese último exit (o return), ya que los hijos están llamando a execl (que los reemplaza por procesos nuevos), pero de todas formas es importante acostumbrarte a finalizar siempre todos tus procesos hijos.
4  Programación / Programación C/C++ / Re: Programacion en C en: 2 Enero 2022, 20:20 pm
Pues se usa igual que con cualquier tipo de archivo:

Código
  1. read(fd[0], buffer, NUM_BYTES);

Al margen de eso, revisa bien tu código y apuntes que tengas, ya que tiene varios errores. Por mencionarte algunos:

Siempre es importante cerrar los descriptors no usados, así que los hijos deberían cerrar fd[0]. De igual forma, después del dup, ya no usas fd[1] directamente (execl usa el descriptor de stdout, que apunta hacia tu pipe), por lo que también es mejor cerrarlo. Por cierto, dup2 es más recomendable que dup, aunque esto es sólo un consejo.

Estás cerrando fd[1] desde dentro del bucle, lo que significa que, a partir de la segunda iteración, estarás intentado duplicar un descriptor ya cerrado. Ese close debe ir fuera del for.

No estás terminando los procesos hijos, así que algunos de ellos van a crear sus propios procesos hijos, además de ejecutar lo que está fuera del bucle, adonde, se supone, sólo debería llegar el padre. Así que debes agregar un exit al final del case 0. Ya que estamos, normalmente es preferible que los procesos hijos finalicen con _exit en vez de exit. En tu caso no lo cambies, pero tenlo en cuenta. Si en algún ejercicio posterior tienes problemas (por ejemplo, que los mensajes salgan repetidos), busca las diferencias entre ambas funciones, ya que ahí podría estar la solución.
5  Programación / Programación C/C++ / Re: ¿Alguien sabe de alguna funcion "gets" que no imprima el salto de linea final? en: 24 Noviembre 2021, 17:59 pm
Si entendí bien, limpiar el buffer no te va a servir para lo que quieres. Luego de presionar Enter, el cursor ya se movió. Que después lo limpies del buffer interno no altera de ninguna manera lo que está en pantalla.

Que yo sepa no hay ninguna función ni modo de consola que permita lo que quieres, pero sí puedes escribir una función propia que haga exactamente lo que necesitas. Podrías implementarla mediante _getch(), por ejemplo.


Alternativamente, podrías reposicionar manualmente el cursor. Por ejemplo:

Código
  1. GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consInfo);
  2. fgets(...);
  3. // calculas el numero de caracteres que se introdujeron, y luego...
  4. consInfo.dwCursorPosition.X += n_caracteres;
  5. SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consInfo.dwCursorPosition);
  6.  

Aclarando que si el número de caracteres introducidos es muy grande y ocupa más de una línea, habría que hacer un par de cálculos más para determinar en que columna y línea se presionó el Enter.
6  Programación / ASM / Re: Error de ld en nasm en: 2 Noviembre 2021, 16:35 pm
Ese mensaje de error significa que el enlazador no encuentra una biblioteca con la que le estás pidiendo que enlace. En este caso, está buscando un archivo libib32.a. Recuerda que la opción -l implica un prefijo "lib" al nombre que le pases, por lo que si el archivo se llamara lib32.a, deberías usar -l32, NO -lib32. Sea como sea, el error es ése, que no encuentra el archivo. Revisa que el nombre sea correcto, y que esté en una ruta que ld pueda encontrar (o agrega esa ruta mediante -L).
7  Programación / Programación C/C++ / Re: funcion limpiar buffer de teclado en: 15 Octubre 2021, 23:57 pm
Pero eso no deja limpio el buffer. Simplemente lee un caracter, justo como si pusieras un "%c" (o un único getchar() después del scanf). El * hace que no lo asigne a una variable, pero por lo demás, no hay mayor diferencia. Sí te sirve suponiendo que siempre introduzcas puros dígitos, pero si, por error (o no) introduces algo como "15 ", o sea, el número con un espacio (o cualquier otro caracter) al final, vas a volver a tener el mismo problema, lo cual no pasa cuando limpias el buffer, por ejemplo con la función que pusiste en el mensaje original.

Hay formas más complejas de scanf que sí pueden limpiarlo (puedes googlear el especificador '[' ), pero tienen sus inconvenientes, por lo que, en mi opinión no valen la pena para este propósito.
8  Programación / Programación C/C++ / Re: funcion limpiar buffer de teclado en: 6 Octubre 2021, 21:34 pm
La clave es limpiar el buffer sólo cuando sabes que no está vacío. ¿Cómo puedes saber esto? Depende, pero de forma muy general, cuando lees, por ejemplo, enteros y flotantes, scanf siempre deja el '\n' en el buffer, por lo que necesitas limpiarlo si la siguiente instrucción de entrada lee caracteres o cadenas. La función gets quita el '\n', así que no tienes que limpiarlo después de llamarla. Si lo haces, se producirá  el mismo problema de tener que introducir dos veces el salto de línea. Si usas fgets, la cosa cambia, pero eso lo puedes consultar en la documentación de esa función en cualquier manual.

P.D. La razón por la que te mencioné que no te aconsejaba la solución con fseek es que, por ejemplo, no funciona en Linux. Esto no es falla del SO, sino que en realidad los "streams", cuando no están asociados a un archivo real, no tienen por qué admitir búsquedas. La entrada estándar del teclado no es un archivo normal, así que puede o no admitirlas. En Windows funciona (por ahora) pero no es seguro saber si siempre lo hará. Esto no es meramente teórico; la propia fflush(stdin) funcionaba antes en Visual C++, y de hecho, la documentación oficial de Microsoft así lo especificaba, y sin embargo, hace unos años eliminaron esa funcionalidad y ya no funciona ni se menciona en la documentación actual. Así que la solución del fseek perfectamente podría dejar de funcionar en la siguiente actualización (o no, quién sabe) sin previo aviso. De cualquier manera, puesto que la manera estándar (como tu función) es tan simple, portable, y su funcionamiento está garantizado, no le veo sentido a usar una que no cumple con estas ventajas. En todo caso, si de todas maneras la quieres usar, deberías considerarla como a gets (algo temporal que igual vale para ejercicios de práctica, pero nada más). Y recomiendo checar esto: https://blog.codinghorror.com/the-works-on-my-machine-certification-program/

Algunas referencias sobre las búsquedas en stdin, por si te interesa.Para mi gusto las explicaciones están algo incompletas, y hay aún más razones para evitarlo, pero no están mal (en particular, la respuesta aceptada del primer linky sus comentarios):

https://stackoverflow.com/questions/16672672/can-fseekstdin-1-seek-set-or-rewindstdin-be-used-to-flush-the-input-buffer-i
https://stackoverflow.com/questions/4917801/using-fseek-with-a-file-pointer-that-points-to-stdin
9  Programación / Programación C/C++ / Re: funcion limpiar buffer de teclado en: 6 Octubre 2021, 17:56 pm
Las formas estándar y portables de hacerlo son sólo variaciones de la que has puesto. En C++ puedes usar cin.ignore:

Código
  1. cin.ignore(tam, '\n');

que lee y descarta hasta "tam" caracteres o hasta encontrar un '\n'. Puedes usar un número muy grande para tam, o bien, numeric_limits<streamsize>::max(), que es el tamaño máximo de un stream:

Código
  1. #include <limits>
  2. ...
  3. cin.ignore(numeric_limits<streamsize>::max(), '\n');

que básicamente significa que limpie todo lo que haya, hasta que encuentre el caracter de línea nueva. Hay alguna otra manera pero a final de cuentas, como te dije, son variaciones de esto.

Eso sí, evita fflush(stdin), que es directamente erróneo aunque a veces funcione. Otra solución que a veces se lee es mediante fseek, pera tampoco deberías usarla. Entre otras cosas no es portable y no hay ni siquiera garantía de que siga funcionando en las plataformas donde actualmente lo hace.

Lo del doble Enter no debería ser necesario. Creo que sé dónde está tu error, pero sería mejor su pusieras un código de ejemplo donde pase.
10  Comunicaciones / Dispositivos Móviles (PDA's, Smartphones, Tablets) / Re: Formatear Telefono Inteligente en: 2 Octubre 2021, 22:09 pm
No soy ningún experto en el tema, pero sí lo he hecho, con una tablet y varios teléfonos. No vas a encontrar una guía universal de cómo hacerlo, ya que el procedimiento varia según el modelo, pero a grandes rasgos,  lo típico es instalar en tu PC drivers adecuados para el dispositivo y herramientas como adb (o según el celular, puede haber programas que te automaticen el proceso y te evitan teclear comandos), y con esto, desbloquear el bootloader, posiblemente flashear uno nuevo, y luego flashear la ROM.

Lo importante es que todo lo que descargues sea para tu modelo específico (incluso el número de revisión puede ser importante). Probablemente el mejor sitio para encontrar las guías y herramientas necesarias es https://forum.xda-developers.com/. Hay subforos para todas las marcas.

Y aunque es cierto que es preferible restaurar de fábrica, no siempre es solución. Si tienes un dispositivo que se quedó en una versión vieja de Android, pero por lo demás está en perfecto estado, puedes meterle una ROM no oficial más reciente y darle nueva vida. Sí se corre el riesgo de dañarlo, pero no es tan fácil. Incluso si le instalas algo incorrecto, muchas veces se puede arreglar vía software, y aún cuando no, la solución suele ser relativamente simple, aunque puede necesitarse alguna herramienta física. En todo caso, suele ser barato, ya sea que lo haga uno mismo o lo lleve a un taller. Con esto no quiero decir que sea imposible causar un daño más severo; siempre hay que ser cuidadosos, pero tampoco es para tener miedo si alguna vez necesitas hacerlo. Simplemente hay que leer y seguir bien las guías.
Páginas: [1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines