imprimir - leer cadenas en c scanf
El programa no espera la entrada del usuario con scanf("% c", & yn); (5)
Este es el código básico de un programa que estoy escribiendo para practicar el uso de archivos en C. Estoy tratando de detectar si el archivo de salida ya existe y si existe, quiero preguntarle al usuario si desea sobrescribirlo o no. Esta es la razón por la que primero abrí el archivo de nombre de archivo de salida con fopen (nombre de archivo de salida, "r"); a diferencia de fopen (nombre de archivo externo, "w") ;.
Detecta el caso de que el archivo no exista, sin embargo, si existe, ejecuta printf ("El archivo de salida ya existe, sobrescribe (y / n):"); declaración, pero ignora por completo el scanf ("% c", y yn); ¡declaración!
El printf al final del programa dice "yn = 0" si el archivo no existe y solo "yn =" si existe. Alguien puede ayudarme?
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
int main(void) {
FILE *inf;
FILE *outf;
char filename[21],outfilename[21];
char yn=''0'';
printf("Please enter an input filename: ");
scanf("%s",&filename);
printf("Please enter an output filename: ");
scanf("%s",&outfilename);
/* Open file for reading */
inf=fopen (filename,"r");
outf=fopen(outfilename,"r");
/*check that input file exists*/
if (inf!=NULL) {
/*check that the output file doesn''t already exist*/
if (outf==NULL){
fclose(outf);
/*if it doesn''t already exist create file by opening in "write" mode*/
outf=fopen(outfilename,"w");
} else {
/*If the file does exist, give the option to overwrite or not*/
printf("Output file already exists, overwrite (y/n):");
scanf("%c",&yn);
}
}
printf("/n yn=%c /n",yn);
return 0;
}
La mejor manera de manejar este problema que encontré se explica aquí .
Recomienda utilizar una forma alternativa de manejo de entrada y está muy bien explicado.
Siempre utilizo esta función para obtener la entrada del usuario.
char * read_line (char * buf, size_t length) {
/**** Copyright de home.datacomm.ch/t_wolf/tw/c/getting_input.html#skip
Read at most ''length''-1 characters from the file ''f'' into
''buf'' and zero-terminate this character sequence. If the
line contains more characters, discard the rest.
*/
char *p;
if ((p = fgets (buf, length, stdin))) {
size_t last = strlen (buf) - 1;
if (buf[last] == ''/n'') {
/**** Discard the trailing newline */
buf[last] = ''/0'';
} else {
/**** There''s no newline in the buffer, therefore there must be
more characters on that line: discard them!
*/
fscanf (stdin, "%*[^/n]");
/**** And also discard the newline... */
(void) fgetc (stdin);
} /* end if */
} /* end if */
return p;
} /* end read_line */
Vieja respuesta
Solucioné este tipo de problemas con esta regla:
// first I get what I want.
c = getchar();
// but after any user input I clear the input buffer
// until the /n character:
while (getchar() != ''/n'');
// this also discard any extra (unexpected) character.
Si haces esto después de cualquier entrada, no debería haber problema.
Utilizar
scanf("%20s",&filename);
y recuerda que stdin está en línea de búfer y en Linux está siguiendo una disciplina tty
Puede usar GNU readline o ncurses si desea un control más detallado.
scanf("%s", ...)
deja / n terminando la línea en la entrada. No está causando ningún problema para el siguiente, ya que scanf ("% s", ...) comienza salteando blancos. scanf("%c", ...)
no lo hace y, por lo tanto, usted lee /n
.
Por cierto, probablemente encontrará otros problemas si coloca espacios en su nombre de archivo ( %s
no los lee) y si ingresa nombres demasiado largos (% s no tiene limitaciones de longitud de entrada).
Una solución para el problema del que se quejó (pero no del otro) es usar scanf(" %c", ...)
(vea el espacio antes de que %c
? scanf
sea difícil de usar) que comienza omitiendo los espacios en blanco.
printf("Please enter an output filename: ");
scanf("%s",&outfilename);
Cuando ingresa la segunda cadena y presiona la tecla ENTRAR, una cadena y un carácter se colocan en el búfer de entrada, son a saber: la cadena ingresada y el carácter de línea nueva. La cadena se consume por el scanf
pero la nueva línea permanece en la entrada buffer.
Promover,
scanf("%c",&yn);
Su próximo scanf
para leer el carácter simplemente lee / consume la nueva línea y, por lo tanto, nunca espera la entrada del usuario.
La solución es consumir la nueva línea adicional usando:
scanf(" %c", &yn);
^^^ <------------Note the space
O mediante el uso de getchar()
Es posible que desee consultar mi respuesta aquí para obtener una explicación detallada del problema paso a paso.
scanf("%s",&filename);
también elimina el &
scanf.c: 13: advertencia: el formato ''% s'' espera el tipo ''char '', pero el argumento 2 tiene el tipo ''char ( ) [20u]''