c

K&R Ejercicio 1-9(C)



(29)

"Escriba 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".

Supongo que con esto quiere decir algo como ...

Nosotros (en blanco) (en blanco) (en blanco) vamos (en blanco) a (en blanco) (en blanco) (en blanco) el centro comercial (en blanco) !

... y lo imprime como

¡Nosotros (en blanco) vamos (en blanco) a (en blanco) el centro comercial (en blanco) !

Probablemente esto sea más fácil de lo que estoy haciendo, pero aún así, parece que no puedo entenderlo. Realmente no quiero el código ... más pseudo código .

Además, ¿cómo debería estar mirando esto? Estoy bastante seguro de que cualquier programa que escriba va a necesitar al menos una variable , un bucle while, un par de sentencias if , y getchar() las getchar() y putchar() ... pero además, estoy en una pérdida. Todavía no tengo un tren de pensamiento para los programadores, así que si me pudiera dar algún consejo sobre cómo debería estar viendo los "problemas" en general, sería genial.

(Y, por favor, no mencione nada else , no he llegado tan lejos en el libro, así que ahora está fuera de mi alcance).


Pseudo codigo

while c = getchar: if c is blank: c = getchar until c is not blank print blank print c

do

Puede sustituir el uso de isblank aquí si lo desea. No se especifica qué caracteres se crean en blanco, o qué valor en blanco se imprimirá en lugar de otros.

Después de muchos puntos hechos por Matthew en los comentarios a continuación, esta versión, y la que contiene isblank son las mismas.

int c; while ((c = getchar()) != EOF) { if (c == '' '') { while ((c = getchar()) == '' ''); putchar('' ''); if (c == EOF) break; } putchar(c); }


Acabo de comenzar el libro y aquí está la solución que encontré usando 3 if enunciados, espero que sea lo suficientemente claro:

#include <stdio.h> #include <stdlib.h> int main() { int c = 0, sp = 0; /* sp for spaces*/ while ((c = getchar()) != EOF){ if (c == '' '') ++sp; /* If character introduced was a space, it starts to count them*/ if (c != '' '') sp = 0; /* If character introduced wasn''t a space, then it resets counter to zero*/ if (sp < 2) putchar(c); /*If there are less than 2 spaces, then the character will be printed, otherwise it won''t (therefore it will always keep only 1 space)*/ } return 0; }


Aquí está mi respuesta, actualmente estoy en el mismo lugar que hace años.

Usé solo la sintaxis que se enseña hasta este momento en los libros y reduce los espacios múltiples en un espacio solo según sea necesario.

#include<stdio.h> int main(){ int c int blanks = 0; // spaces counter while ((c = getchar()) != EOF) { if (c == '' '') { // if the character is a blank while((c = getchar()) == '' '') { //check the next char and count blanks blanks++; // if(c == EOF){ // break; // } } if (blanks >= 0) { // comparing to zero to accommodate the single space case, // otherwise ut removed the single space between chars putchar('' ''); // print single space in all cases } } putchar(c); //print the next char and repeat } return 0; }

Quité la parte de descanso ya que aún no se introdujo en el libro, espero que esto ayude a los nuevos como yo :)


Así es como pienso en el algoritmo de este ejercicio, en pseudocódigo:

define ch and bl (where bl is initially defined to be 0) while ch is = to getchar() which is not = to end of file do the following: if ch is = to blank and bl is = 0 --> output ch and assign the value 1 to bl else --> if ch is = to blank and bl is = 1 --> do nothing else --> output ch and assign the value 0 to bl

Ejemplo de implementación en C:

#include <stdio.h> #include <stdlib.h> main() { long ch,bl=0; while ((ch=getchar()) != EOF) { if (ch == '' '' && bl == 0) { putchar(ch); bl=1; } else if (ch == '' '' && bl == 1) { // no-op } else { putchar(ch); bl=0; } } return 0; }


Como muchas otras personas, también estoy estudiando este libro y me pareció muy interesante esta pregunta.

He creado un código que solo usa lo que se explicó antes del ejercicio (ya que no estoy consultando ningún otro recurso sino simplemente jugando con el código).

Hay un bucle while para analizar el texto y uno para comparar el carácter actual con el anterior. ¿Hay casos extremos en los que este código no funcionaría?

#include <stdio.h> main() { // c current character // pc previous character int c, pc; while ((c = getchar()) != EOF) { // A truthy evaluation implies 1 // (learned from chapter 1, exercice 6) // Avoid writing a space when // - the previous character is a space (+1) // AND // - the current character is a space (+1) // All the other combinations return an int < 2 if ((pc == '' '') + (pc == c) < 2) { putchar(c); } // update previous character pc = c; } }


Dado que los operadores relacionales en C producen valores enteros 1 o 0 (como se explicó anteriormente en el libro), la expresión lógica "carácter actual no en blanco o carácter anterior no en blanco" puede simularse con aritmética de enteros dando como resultado un valor más corto (aunque algo críptico) ) código:

int c, p = EOF; while ((c = getchar()) != EOF) { if ((c != '' '') + (p != '' '') > 0) putchar(c); p = c; }

La variable p se inicializa con EOF para que tenga un valor válido que no esté en blanco durante la primera comparación.


Escribí esto y parece estar funcionando.

# include <stdio.h> int main () { int c,lastc; lastc=0; while ((c=getchar()) != EOF) if (((c=='' '')+ (lastc=='' ''))<2) putchar(c), lastc=c; }


Esta es una solución que utiliza solo las técnicas descritas hasta ahora en K&R C. Además de usar una variable para lograr un cambio de estado finito para distinguir el primer espacio en blanco de los espacios en blanco sucesivos, también agregué una variable para contar espacios en blanco junto con una declaración de impresión para verificar el número total. Esto me ayudó a envolver mi cabeza alrededor de getchar() y putchar() un poco mejor, así como el alcance del bucle while dentro de main ().

// Exercise 1-9. Write a program to copy its input to its output, replacing // each string of one or more blanks by a single blank. #include <stdio.h> int main(void) { int blank_state; int c; int blank_count; printf("Replace one or more blanks with a single blank./n"); printf("Use ctrl+d to insert an EOF after typing ENTER./n/n"); blank_state = 0; blank_count = 0; while ( (c = getchar()) != EOF ) { if (c == '' '') { ++blank_count; if (blank_state == 0) { blank_state = 1; putchar(c); } } if (c != '' '') { blank_state = 0; putchar(c); } } printf("Total number of blanks: %d/n", blank_count); return 0; }


Esto es lo que conseguí:

while ch = getchar() if ch != '' '' putchar(ch) if ch == '' '' if last_seen_ch != ch putchar(ch) last_seen_ch = ch


Estoy en el mismo punto del libro. y mi solución es hacer una cuenta ++ si se encuentra en blanco y hacer que la cuenta vuelva a cero si se encuentra algo más que en blanco.

Para la instrucción if, puse otra verificación para verificar el valor de conteo (si es cero) y luego imprima.

Aunque en este punto de aprendizaje no debería preocuparme la eficiencia de dos métodos, sino cuál es eficiente a.) Solución aceptada aquí con tiempo dentro o b.) El que sugerí anteriormente.

Mi código va como abajo:

#include <stdio.h> main() { int count=0,c; for( ; (c=getchar())!=EOF; ) { if(c=='' '') { if(count==0) { putchar(c); count++; } } if(c!='' '') { putchar(c); count=0; } } }


La misma explicación con Matt Joiner, pero este código no usa break .

int c; while ((c = getchar()) != EOF) { if (c == '' '') /* find a blank */ { putchar('' ''); /* print the first blank */ while ((c = getchar()) == '' '') /* look for succeeding blanks then… */ ; /* do nothing */ } if (c != EOF) /* We might get an EOF from the inner while-loop above */ putchar(c); }


Mira tu programa como una máquina que se mueve entre diferentes estados a medida que itera sobre la entrada.

Lee la entrada un carácter a la vez. Si ve algo más que un espacio en blanco, simplemente imprime el carácter que ve. Si ve un espacio en blanco, cambia a un estado diferente. En ese estado, imprime un espacio en blanco, y luego no imprime espacios en blanco si los ve. Luego, continúa leyendo la entrada, pero ignora todos los espacios en blanco que ve, hasta que llega a un carácter que no está en blanco, momento en el que vuelve al primer estado.

(Este concepto se denomina máquina de estados finitos , por cierto, y se ha realizado un gran trabajo teórico informático sobre lo que pueden y no pueden hacer. Wikipedia puede ofrecerle más información, aunque quizás con más detalles que usted. buscando. ;))


Para hacer esto usando solo bucles while y sentencias if, el truco es agregar una variable que recuerde el carácter anterior.

Loop, reading one character at a time, until EOF: If the current character IS NOT a space: Output current character If the current character IS a space: If the previous character WAS NOT a space: Output a space Set previous character to current character

En código C:

#include <stdio.h> main() { int c, p; p = EOF; while ((c = getchar()) != EOF) { if (c != '' '') putchar(c); if (c == '' '') if (p != '' '') putchar('' ''); p = c; } }


Primero declare dos variables carácter y último_caracter como enteros.cuando no haya llegado al final del archivo (mientras que (carácter = getchar ()! = EOF) haga esto; 1. Si el carácter! = '''', Imprima el carácter último_caracter = carácter 2 . Si el carácter == '''' si last_character == '''' el último carácter = el carácter más imprime el carácter


También estoy empezando con el libro de texto de K&R, y se me ocurrió una solución que usa solo el material que había sido cubierto hasta ese momento.

Cómo funciona:

Primero, ponga algunos ''espacios en blanco'' en cero. Esto se usa para contar espacios en blanco.

Si encuentra un espacio en blanco, aumente los "espacios en blanco" del contador en uno.

Si no se encuentra un espacio en blanco, primero haga una prueba secundaria: ¿el ''espacio en blanco'' del contador es igual o mayor que 1? En caso afirmativo, primero imprima un espacio en blanco y, a continuación, vuelva a poner los "espacios en blanco" del contador.

Una vez que se haya realizado esta subprueba, vuelva atrás y ponga cualquier carácter que no se haya encontrado en blanco.

La idea es, antes de colocar un carácter que no esté en blanco, primero hacer una prueba para ver, si se contaron algunos espacios en blanco antes. Si había espacios en blanco antes, imprima primero un espacio en blanco y luego restablezca el contador de espacios en blanco. De esa manera, el contador vuelve a ser cero para la siguiente ronda de espacios en blanco. Si el primer carácter de la línea no está en blanco, el contador no podría haber aumentado, por lo que no se imprime ningún blanco.

Una advertencia, no he avanzado mucho en el libro, por lo que aún no estoy familiarizado con la sintaxis, por lo que es posible que las llaves {} estén escritas en diferentes lugares, pero mi ejemplo funciona bien.

#include <stdio.h> /* Copy input to output, replacing each string of one or more blanks by a single blank. */ main() { int c, blanks; blanks = 0; while ((c = getchar()) != EOF) { if (c != '' '') { if (blanks >= 1) printf(" "); blanks = 0; putchar(c); } if (c == '' '') ++blanks; } }


Teniendo en cuenta lo que se pregunta en la pregunta, ¡también me aseguré de que el programa se ejecute sin problemas en el caso de varias pestañas, espacios y cuando se agrupan para formar varias combinaciones! Aquí está mi código,

int c, flag = 1; printf("Enter the character!/n"); while ((c = getchar()) != EOF) { if (c == '' ''||c == ''/t'') { c=getchar(); while(c == '' ''|| c == ''/t'') { c = getchar(); } putchar('' ''); if (c == EOF) break; } putchar(c); }

Siéntase libre de ejecutar todos los casos de prueba utilizando varias combinaciones de espacios y pestañas.


Trabajé muy duro para encontrar una solución que utilizara solo el material que ya se ha cubierto en la primera parte del primer capítulo del libro. Aquí está mi resultado:

#include <stdio.h> /* Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank. */ main() { int c; while ((c = getchar()) != EOF){ if (c == '' ''){ putchar(c); while ((c = getchar()) == '' '') ; } if(c != '' '') putchar(c); } }


Usando las restricciones de no usar otro u o operadores. Este código solo imprime un espacio en blanco cuando la variable en blanco es igual a 1 y la única manera de restablecer el contador es escribir algo que no sea un espacio en blanco. Espero que esto ayude:

incluir

/ * Escriba un programa que reemplace cadenas de espacios en blanco con un solo espacio en blanco * /

void main () {int c, bl;

bl = 0; while((c = getchar()) != EOF){ if(c == '' ''){ ++bl; if(bl == 1){ putchar('' ''); } } if(c != '' ''){ putchar(c); bl = 0; } }

}


una forma de facilitar que las nuevas personas queden atrapadas en este libro (al no saber nada de lo que se mencionó hasta la página 22 en K&R).

créditos a @Michael, @Mat y @Matthew para ayudarme a entender

#include <stdio.h> main() { int c; while ((c = getchar()) != EOF) /* state of "an input is not EOF" (1) */ { if (c == '' '') /* "blank has found" -> change the rule now */ { while ((c = getchar ()) == '' ''); /* as long you see blanks just print for it a blank until rule is broken (2) */ putchar('' ''); } putchar(c); /* either state (2) was broken or in state (1) no blanks has been found */ } }


#include <stdio.h> main() { int input, last = EOF; while ((input = getchar()) != EOF) { if (input == '' '' && last == '' '') continue; last = input; putchar(input); } }


#include <stdio.h> int main() { int c; while( (c = getchar( )) != EOF ) { if (c == '' '') { while ((c = getchar()) == '' ''); putchar('' ''); putchar(c); } else putchar(c); } return 0; }


#include <stdio.h> int main(void) { long c; long nb = 0; while((c = getchar()) != EOF) { if(c == '' '' || c == ''/t'') { ++nb; } else { if(nb > 0) { putchar('' ''); nb = 0; } putchar(c); } } return 0; }


#include <stdio.h> main() { int c, numBlank=0 ; while((c= getchar())!=EOF) { if(c =='' '') { numBlank ++; if(numBlank <2) { printf("character is:%c/n",c); } } else { printf("character is:%c/n",c); numBlank =0; } } }


#include <stdio.h> main() { int CurrentChar, LastChar; LastChar = ''1''; while ((CurrentChar = getchar()) != EOF) { if (CurrentChar != '' '') { putchar(CurrentChar); LastChar = ''1''; } else { if (LastChar != '' '') { putchar(CurrentChar); LastChar = '' ''; } } } }


#include<stdio.h> #include<stdlib.h> int main(void) { int c, flag=0; while((c=getchar()) != EOF){ if(c == '' ''){ if(flag == 0){ flag=1; putchar(c); } }else{ flag=0; putchar(c); } } return 0; }

Espero que esto sea de ayuda.


/*a program that copies its input to its output, replacing each string of one or more blanks by a single blank*/ #include <stdio.h> #include<stdlib.h> int main(void) { double c; char blank = '' ''; while((c = getchar()) != EOF) { if(c == '' '') { putchar(c); while(( c = getchar() )== '' '') { if(c != '' '') break; } } if(c == ''/t'') { putchar(blank); while((c = getchar()) == ''/t'') { if(c != ''/t'') break; } } putchar(c); } return 0; }


// K & R Exercise 1.9 // hoping to do this with as few lines as possible int c = 0, lastchar = 0; c = getchar(); while (c != EOF) { if (lastchar != '' '' || c != '' '') putchar(c); lastchar=c; c=getchar(); }


for(nb = 0; (c = getchar()) != EOF;) { if(c == '' '') nb++; if( nb == 0 || nb == 1 ) putchar(c); if(c != '' '' && nb >1) putchar(c); if(c != '' '') nb = 0; }


1.Count the number of blanks. 2.Replace the counted number of blanks by a single one. 3.Print the characters one by one. <code> main() { int c, count; count = 0; while ((c = getchar()) != EOF) { if (c == '' '') { count++; if (count > 1) { putchar (''/b''); putchar ('' ''); } else putchar ('' ''); } else { putchar (c); count = 0; } } return; } </code>