He estado trabajando en algunos libros sobre C tratando de obtener mis piernas C (¡piernas marinas! ¿Lo entiendes?). Acabo de terminar el ejercicio 1-9 del libro K&R, que como referencia es "escribir un programa para copiar su entrada a su salida, reemplazando cada cadena de uno o más espacios en blanco por un solo espacio en blanco". Sin embargo, tengo una pregunta sobre lo que está pasando con mi código:
#include <stdio.h> //Copy input to output. Replace each string of multiple spaces with one single space int main(int argc, char *argv[]){ int ch, lch; // Variables to hold the current and last characters, respectively /* This loop should 'put' the current char, then store the current char in lc, * loop back, 'get' a new char and check if current and previous chars are both spaces. * If both are spaces, do nothing. Otherwise, 'put' the current char */ for(ch = getchar(); (ch = getchar()) != EOF; lch = ch){ if(ch == ' ' && lch == ' ') ; else putchar(ch); } return 0; }Esto funciona principalmente, excepto por la entrada de primer carácter. Por ejemplo, si la entrada de la primera línea es
"This is a test"mis salidas de código
"his is a test".Después de descartar la entrada del primer carácter, el programa funciona consistentemente para satisfacer las demandas del ejercicio.
¿Alguien puede darme una idea del error que cometí en mi ciclo que está causando el problema? Cualquier otro consejo es bienvenido también.
En la instrucción for-loop, tiene el error.
for(ch = getchar(); (ch = getchar()) != EOF; lch = ch){...}Aquí, está almacenando el primer carácter en ch, y luego nuevamente probando si (ch! = EOF) leyendo nuevamente la entrada de caracteres.
Elimina ch=getchar() de la declaración de inicialización; que sea en la segunda parte.
for(;(ch = getchar()) != EOF; lch = ch){...} Además, deberá inicializar su lch antes de ejecutarlo, ya que lch no tendrá ningún valor almacenado antes de realizar la comparación en la primera iteración del bucle. Por lo tanto, permita que lch=0 se inicialice primero.
for(lch = 0; (ch = getchar()) != EOF; lch = ch){...}Considere habilitar las advertencias en su compilador, probablemente detectaría y advertiría sobre este problema, para que pueda solucionarlo.
Lo anterior resolvería tu problema.
(Gracias a Blue Moon y hyde por ayudarme a modificar la respuesta).
Llamas a getchar dos veces en la inicialización del bucle:
for(ch = getchar(); (ch = getchar()) != EOF; lch = ch)En su lugar, debe llamarlo una vez en la inicialización (para obtener el primer carácter) y luego al final de la iteración (para obtener los siguientes caracteres):
int ch, lch = 0; // avoid using uninitialized variable for(ch = getchar(); ch != EOF; lch = ch) { if(ch == ' ' && lch == ' ') ; else putchar(ch); ch = getchar(); }UPD: Gracias Blue Moon y shekhar suman por señalar el problema con lch
El problema es que la primera iteración de su bucle llama a getchar dos veces: una vez al inicializar la variable ch y una vez más al comparar ch con EOF .
ch = getchar() solucionará este problema:
for( lch = '?' ; (ch = getchar()) != EOF; lch = ch) { ... } Tenga en cuenta que debe lch con cualquier valor que no sea espacio.