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 - RayR

#1
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:


GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consInfo);
fgets(...);
// calculas el numero de caracteres que se introdujeron, y luego...
consInfo.dwCursorPosition.X += n_caracteres;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), consInfo.dwCursorPosition);


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.
#2
ASM / Re: Error de ld en nasm
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).
#3
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.
#4
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
#5
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 (cpp) [Seleccionar]
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 (cpp) [Seleccionar]
#include <limits>
...
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.
#6
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.
#7
Redes / Re: Internet sin ping (problema)
26 Septiembre 2021, 20:59 PM
Por lo que dices, probablemente sea cosa de tu ISP. Muchas veces estas cosas pasan por problemas de DNS, pero no me parece que sea tu caso. Imagino que habrás probado hacer ping a otras URLs e incluso direcciones IP ¿no? Por ejemplo, ¿puedes hacer ping a 8.8.8.8? Si te da el mismo error, seguramente sea un problema específico del ping, lo cual también explicaría lo del WoW, pues muchos juegos en línea lo requieren. Si es así, seguro es un problema temporal; quizás tu ISP siga con problemas técnicos, o haya deshabilitado momentáneamente el tráfico ICMP por seguridad o algo por el estilo. En todo caso, si dura más de un día, yo los llamaría a ellos.
#8
Android / Re: Recomendación de Smartphone
21 Septiembre 2021, 21:50 PM
Cita de: DonPilin en 21 Septiembre 2021, 13:34 PM
Alguien sabe como hacer para que un celular muestre si funciona con 2,4 G o 5G de wifi?Gracias

Trata de no mezclar los términos, o vas a ocasionar confusión. 5G y 5 GHz son cosas completamente diferentes. Si hablas de wifi, las bandas son 2.4 GHz y 5 GHz. En este caso, lo único que necesitas es verificar si admite la de 5 GHz (si tiene wifi, se da por sentado que soporta la de 2.4 GHz). La forma de comprobar esto varía según la versión de Android, pero una manera sencilla es simplemente ver si detecta redes de 5 GHz. O puedes instalar alguna app, como DevCheck, que en el apartado de red te da esa información.
#9
Programación C/C++ / Re: extension .inl y .hpp
17 Septiembre 2021, 00:40 AM
Esas extensiones no tienen nada de especial, simplemente hay quienes las usan para hacer explícitas ciertas cosas.

Como sabrás, en C++ es común poner las declaraciones de funciones (y las "interfaces" de clases) en archivos de cabecera .h, y las implementaciones o definiciones en .cpp. Las cabeceras se incluyen con directivas #include , y los .cpp se compilan individualmente, y los archivos compilados resultantes se enlazan para formar el archivo final, por ejemplo .exe. Con las plantillas no se puede hacer eso, sino que también las definiciones se deben incluir en los archivos fuente como si se tratara de cabeceras (esto no es totalmente cierto, y en realidad es más complejo, pero es "correcto" de forma general). La opción más obvia sería poner las definiciones directamente en las cabeceras, pero normalmente es preferible hacer la separación de interfaz e implementación, aunque sea sólo por legibilidad. Otra forma de hacerlo es seguir separando el código con plantillas en cabeceras y  archivos .cpp, pero incluir los propios .cpp con directivas #include, justo como con los .h. Sin embargo, esto podría prestarse a confusiones. Un programador que reciba archivos .cpp y .h, podría suponer que los .cpp se deben compilar por separado, como es lo normal, pero dado que estamos hablando de plantillas, eso sería incorrecto. Si, en cambio, se usa otra convención, es posible evitar esas ambigüedades. En este caso, se supone que si el programador ve archivos .inl, sabe que no debe incluirlos para compilarse en el proyecto, sino simplemente usar las cabeceras que desee (las cuales a su vez se encargan de incluir las implementaciones, dado que son .hpp), y ya está.

Esto no es algo generalizado, y no todos lo usan, ni lo conocen. Al final da igual la convención que se use, siempre que todos los que vayan trabajar en un proyecto la conozcan y se apeguen a ella, así que no le veo mucho sentido a recomendar o no su uso. Es simplemente una opción.
#10
Es normal lo que pasa, dado que el GetAsyncKeyState únicamente se llama al inicio de cada iteración del bucle. Una vez que entras a él, todo lo que está dentro del bloque se ejecuta, y después se hace la comprobación.

La forma en que estás usando esta función (verificando el bit menos significativo) no está mal, pero puede dar problemas y no se recomienda mucho su uso. Mira aquí (en concreto lo de "Although the least significant bit..."): https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate#remarks

Para ejercicios de prueba lo puedes usar, pero lo recomendable es limitarse a probar el bit más significativo (GetAsyncKeyState(codigo) & 0x8000), aunque no hace lo mismo, y en este caso probablemente no te sirva. De todas formas, tu código tiene un problema de fondo, y es que funciones como GetAsyncKeyState no se llevan muy bien con los mecanismos de entrada estándar de C++, como cin, getchar, etc, y es mejor evitar mezclarlos así. Mejor haz algo como lo que te puso  Locura_23, aunque en ese caso, deberías limpiar el buffer antes del cin.get, o leerá el '\n' dejado por el cin anterior. No sé si sepas hacerlo, pero por si no, una forma con cin.ignore:

Código (cpp) [Seleccionar]
#include <limits>
...
while (...) {
...
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.get(controlUsuario);
}


Aunque hay otras igualmente válidas. Simplemente hay que evitar las que involucran fflush o fseek. Obviamente, a diferencia de GetAsyncKey, con cin.get, el usuario deberá presionar Enter después de la 's', pero no me parece que eso sea un problema.