Salir del bucle cuando presiono enter (progtwigción C)

Tengo un pequeño problema con mi progtwig. Estoy tratando de codificar. Básicamente quiero ingresar un símbolo uno por uno dentro de mi bucle y cuando termine, solo quiero presionar Entrar para salir del bucle y luego imprimir. fuera de la cadena a la consola. Sin embargo, esto no parece funcionar y lo he intentado durante horas sin controlarlo. Este es mi codigo

#include  int main(int argc, char *argv[]){ int i = 0; char text[i]; char symbol; while(1){ scanf("%s", &symbol); if(symbol == 13){ //13 should be the ascii value for enter break; } text[i] = symbol; i++; } printf("%s", text); getch(); return 0; } 

  • %s lee una palabra. Si quieres leer un carácter con scanf , usa %c .
  • Las cadenas C terminan en NUL, primero debe terminar la cadena antes de imprimirla.
  • char text[i]i es cero en este punto. No podrás guardar tu cadena aquí. Conozca el tamaño máximo en el momento de la comstackción (y verifique en el tiempo de ejecución cuando se adjunta) o asigne dinámicamente la memoria según sea necesario.

Nota: el escaneo desnudo de la secuencia solo está pidiendo muchos problemas. Prefiero leer líneas.

Puedes configurar tu terminal en modo raw con termcaps:

 term.c_lflag &= ~(ICANON); term.c_lflag &= ~(ECHO); term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; if (tcsetattr(0, TCSADRAIN, &term) == -1) return (-1); 

Luego usa la función:

 int main(int ac, char **av, char **env) { char *name_term; struct termios term; if ((name_term = getenv("TERM")) == NULL) return (-1); if (tgetent(NULL, &name_term) == ERR) return (-1); if (tcgetattr(0, term) == -1) return (-1); grab_key(); return (0); } int grab_key() { char buffer[3]; while (1) { read(0, buffer, 3); if (buffer[0] == 13) printf("Exit !"); } return (0); } 

Y para configurar su terminal en modo “normal”:

 struct termios term; if (tcgetattr(0, &term) == -1) return (-1); term.c_lflag = (ICANON | ECHO); if (tcsetattr(0, 0, &term) == -1) return (-1); 

Tres cuestiones. La primera es cómo estás leyendo los personajes:

 scanf("%s", &symbol); 

El especificador de formato %s es para leer en una cadena. No estás pasando una cadena, sino la dirección de un personaje. Esto resultará en la lectura de scanf en varios caracteres, comenzando con la dirección del symbol y continuando en cualquier byte que pueda seguir. Este es un comportamiento indefinido.

Para leer en un solo carácter, use el especificador de formato %c lugar:

 scanf("%c", &symbol); 

Segundo problema:

 if(symbol == 13){ 

Una nueva línea no es necesariamente ASCII 13 en todos los sistemas. Utilice el código de escape para una nueva línea en su lugar:

 if(symbol == '\n'){ 

Tercer tema:

 int i = 0; char text[i]; 

Esto crea una matriz de tamaño 0. Para mantener las cosas simples, dale a esta matriz un tamaño fijo conocido:

 char text[100]; 

Tu bucle debería verificar que no ingreses demasiados caracteres.

Primero, los arreglos no aumentan su tamaño mágicamente, solo porque aumenta la variable que usó para establecer su tamaño (la i en el text[i] en su código), debe asignar memoria dinámicamente ( malloc , realloc o calloc ), y recuerde para liberarlo. Tu código debería ser así:

 int main(int argc, char *argv[]){ int i = 0; char* text = malloc(sizeof(char)); char symbol; char* aux; while(1){ symbol = getchar(); //Use getchar to read only one char, scanf would be more problematic if(symbol == 13){ //13 should be the ascii value for enter break; } text[i] = symbol; if ((aux = (char*)realloc(text, sizeof(char)*(i+1))) == NULL){ // Handle error return -1; } text = aux; i++; } text[i] = '\0'; //Remember to set last char in your string to '\0' or printf won't work properly printf("%s", text); free(text); getch(); return 0; } 

Puede usar fgetc (3) pero probablemente no funcione (ya que stdin está almacenado en el búfer en la biblioteca estándar de C -ver setvbuf (3) , y en el kernel para ttys, lea más sobre ttys ). Por lo tanto, toda la línea se envía a su progtwig solo cuando el usuario presiona la tecla de retorno .

En la práctica, es muy específico del sistema operativo; Espero que estés en Linux o en algún otro sistema POSIX. Recomiendo fuertemente usar ncurses o readline ; ver también termios (3)

En Windows, cuando presiona Entrar , se lee como \r\n , no simplemente \r . Así que es posible que desee probar esto:

 while(1){ scanf("%c", &symbol); //use %c to read a character if(symbol == '\r'){ scanf("%c", &symbol); if(symbol == '\n') break; } text[i] = symbol; i++; } 

Además, estás creando una matriz de nada y luego intentas colocar datos en ella. Esto no funcionará. Es mejor que asignes un poco de memoria primero y solo luego lees en ella:

 char text[1024]; int i =0; // then increase i up to 1023 

Lo que es más, si su única intención es capturar el hit Enter , no necesitará ningún text , solo el symbol adaptará a sus necesidades.