¿Por qué este código no está comprimiendo espacios correctamente?

Estoy trabajando a través del lenguaje de progtwigción The C de K&R. Estoy trabajando en un ejercicio que dice “Escribir un progtwig que copie toda su entrada a su salida, reemplazando cada cadena de uno o más espacios en blanco por un solo espacio en blanco”.

Creo que lo he resuelto. Algo. Cuando ejecuto el progtwig por primera vez con a.out , puedo escribir un número con varios espacios y lo devolveré con solo un espacio. Pero, cuando vaya a la siguiente línea y vuelva a intentarlo, devolverá los números sin espacios. Además, si escribo una cadena de letras como ” 33 33 33 “, solo quedará un espacio para toda la línea. Se convierte en ” 33 3333 “.

Sé que solo podría buscar en Google la respuesta al ejercicio en sí, pero no creo que eso me ayude a saber por qué mi código se está comportando de la manera en que lo es. Cualquier ayuda sería muy apreciada.

 main() { int c, nl, upper; nl = 0; upper = 2; while( ( c = getchar() ) != EOF ) { if( c == ' ' ) { ++nl; if( nl >= upper ) { --c; --nl; } } putchar(c); } } 

Buen bash. Pero has cometido algunos errores.

No configuró el valor inicial del contador cuando se encuentra otro carácter, entonces se encuentra el espacio. Entonces, si su entrada tiene múltiples espacios en blanco entre los caracteres que no son espacios en blanco como 33 33 33 entonces se imprimirá el primer espacio en blanco y se omitirán otros. Así que la salida sería 33 3333

Debe comprender que el tipo de datos char solo almacena un único carácter y en la encoding ASCII. Cuando aplicas operaciones aritméticas en char, solo cambia el valor del carácter. Entonces, cuando disminuyes la variable char, se refiere a otro personaje. Así que en última instancia, imprime valor de la basura.

Prueba este.

 while ((c = getchar()) != EOF){ if (c == ' '){ ++nl; if (nl >= upper){ continue; } } else{ nl=0; } putchar(c); } 

La lógica es simple …
Si hay varios espacios, coloque el primer espacio y omita otros.

 int main() { int c, nl; nl = 0; while ((c = getchar()) != EOF) { if (c == ' ') { nl ++; } else { nl = 0; } if (nl <= 1) { putchar(c); } } return 0; } 

La solución que ha publicado es más complicada de lo que debe ser: también realiza algunas operaciones que me parecen sin sentido, como c -= ' ' .

Creo que deberías practicar el diseño de algoritmos y la resolución de problemas en general, fuera de la progtwigción en cualquier lenguaje específico. Piensa en cómo lo harías tú mismo si no dieras nada más que escribir cadenas y un trozo de papel cuadrado y un lápiz.

En el pseudocódigo, la solución mínima es la siguiente:

 1. Read character C from input (if there is no input, end program) 2. If character is a space character: 2.1. Was the last printed character a space character too? If so, don't print anything and loop back to step 1. 3. Else, print character C and loop back to step 1. 

En C, esto puede escribirse mínimamente (en C11) como:

 int main( void ) { bool last_char_was_space = false; int c; while( ( c = getchar() ) != EOF ) { if( last_char_was_space ) { if( c == ' ' ) continue; // don't print anything else { putchar( c ); last_char_was_space = false; } } else { putchar( c ); if( c == ' ' ) { last_char_was_space = true; } } } return 0; } 

Este progtwig es un ejemplo simple de una “máquina de estado finito”, que es un ejemplo de un algoritmo con estado y el bloque de construcción fundamental de cosas como expresiones regulares y otros tipos de analizadores. Es una técnica esencial para familiarizarse si desea escribir un progtwig que pueda procesar datos rápidamente con el máximo rendimiento y el mínimo uso de memoria.