2010-09-02 20 views
6

He el siguiente programa:¿Por qué este programa C imprime caracteres extraños en la salida?

#include <stdio.h> 

int main() 
{ 
     int ch; 
     while(ch = getchar() != '\n') { 
       printf("Read %c\n",ch); 
     } 
     return 0; 
} 

No importa lo que entro me sale:

Read 

Por qué sucede esto y qué es tan raro carbón que veo?

Stackoverflow no está imprimiendo el extraño carácter. Se puede ver aquí: http://ideone.com/EfZHr

+1

Si estaba utilizando gcc, asegúrese de que tiene establecido el indicador de -Wall. Entre los muchos problemas comunes que informa es este. – JeremyP

Respuesta

18

Es necesario colocar entre paréntesis como:

while((ch = getchar()) != '\n') 

Precedence de != es mayor que la de =

while(ch = getchar() != '\n') 

es igual a:

while(ch = (getchar() != '\n')) 

que dice un char se compara con nueva línea y luego asigna el resultado de la comparación a ch. Ahora bien, el resultado de la comparación es 0 (cuando se introduce nueva línea) o 1 (cuando se introduce cualquier otra cosa)

El carbón raro que se está viendo es la control char con valor 1, no hay ningún símbolo ASCII imprimible para 1, por lo Supongo que es el caparazón que imprime el raro char con el valor 0001 en él.

Puede confirmarlo mediante la canalización de su salida del programa de volcado octal (OD):

$ echo 'a' | ./a.out | od -bc   # user entered 'a' 
0000000 122 145 141 144 040 001 012 
      R e a d  001 \n 
here you go ----------------^ 


$ echo '\n' | ./a.out | od -bc  # user entered '\n' 
0000000 

GCC cuando se utiliza con -Wall se advierte que:

warning: suggest parentheses around assignment used as truth value 
+1

Referencia de búsqueda de la misma precedencia: D –

1
ch = getchar() != '\n' 

Escribiendo esto causará comportamiento inesperado según los idiomas operator precedence. En C = se evalúa después de != para que ch sea verdadero o falso. Proveedores:

(ch = getchar()) != '\n' 
+1

¿No tiene palabras más claras que signifiquen un fracaso miserable? –

+0

De hecho, no sé por qué elegí esa redacción ayer, pero la cambié. –

2

C (y C++) interpretar el bucle while como:

while(ch = (getchar() != '\n')) { 

Así ch obtiene el valor 1 (por cierto), que es un carácter no imprimible. Debe utilizar paréntesis explícita para fijar la precedencia:

while((ch = getchar()) != '\n') { 
+3

C, no C++ buddy. – Puppy

+0

Ah, de hecho. Pero esto aplica para ambos :) – bdonlan

Cuestiones relacionadas