0
votes

Pourquoi ce code imprime-t-il des lignes et non des caractères simples

#include <stdio.h>
int main()
{
  int c;
  while((c=getchar())!=EOF)
  putchar(c);
  return 0;
}
In my limited exposure to C,as long as C!=EOF the while condition will get executed which essentially will print c and then wait for the next char and try to examine of that does or does not violate the condition. Hence for each char we put enter the putchar will execute.
However when I ran the executable what seemed to happen was the print statement would work only when I pressed for new line (Enter) and it had a buffer of some sort which would print the whole line in the input.
I fail to see any buffer in the code that will hold the chars until a new line is pressed,so what is being done here ?
Where is these chars getting stored until a new line is pressed ?

3 commentaires

Dans votre terminal, et après avoir frappé Entrée, dans le fichier struct utilisé pour une entrée standard.


Comment distinguez-vous que vous lisez des caractères en ligne ou individuellement? Votre programme fonctionne très rapidement et ne vous donne probablement pas de chance de voir comment cela se passe. Le terminal fonctionne en mode ligne pour vous permettre de modifier l'entrée avant de l'envoyer au programme. Voir ma réponse pour une explication plus complète.


"Alors, ce qui est fait ici" votre terminal / console / tout ce qui est intelligent et vous permettant de modifier votre entrée avant de l'envoyer au programme. "Où sont ces caractères sont stockés jusqu'à ce qu'une nouvelle ligne soit enfoncée" dans le pilote terminal. De plus, il y a des tampons (que vous pouvez désactiver) dans la bibliothèque standard.


3 Réponses :


2
votes

Lorsque vous lisez à partir de la console comme ceci, votre programme ne reçoit aucune entrée du tout avant que vous appuyiez sur ENTER, puis surveille et traite la ligne entière à la fois.

Votre programme n'a aucune idée de ce que ces personnages existent même jusqu'à ce que vous appuyez sur Entrée, à ce moment-là qu'ils sont envoyés au tampon STDIN. À partir de là, votre boucle lira et imprimez chaque caractère (y compris la nouvelle ligne) jusqu'à ce que le tampon soit vide (ce qui signifie qu'elle attendra plus d'entrée), ou la fin du fichier est atteinte.


0 commentaires

1
votes

Le tampon se produit dans la lecture des données et l'écriture des données.

stdin et stdout peut être indépendamment caractère , ligne ou complètement tamponné.

Dans votre cas commun, les deux sont ligne tamponnés.

L'entrée n'est pas donnée à getchar () jusqu'à entrez ( '\ n' ) est touché. (Pouvez-vous entrer une entrée d'espace?) Et la sortie n'est pas affichée avant qu'un '\ n' est imprimé.


5 commentaires

Ceci est un peu trompeur. La manipulation de l'espace de retour et similaires sont indépendantes de la tampon. Cela se produit en dehors du programme. L'entrée n'est pas donnée à le programme jusqu'à ce que l'entrée soit touchée. Le tampon arrive sur le dessus.


@ n.m. "L'entrée est accordée au programme jusqu'à ce que l'entrée soit touchée." -> C'est une implémentation possible et non requise (elle est assez courante). Le "pouvez-vous saisir l'espace de retour?" était destiné à OP d'essayer de voir que la clé avant et la clé arrière de l'espace de retour ne figurait probablement pas dans stdin et par conséquent que la mise sous-champ de l'entrée se produise quelque part Sortie comme op suggère.


Presque rien n'est requis. Il n'est pas nécessaire qu'un terminal est un "périphérique interactif" par exemple. Je parle de la situation réelle plutôt que de toute situation possible autorisée par la norme.


@ n.m. "L'entrée n'est pas donnée au programme tant que l'entrée est touchée." n'est souvent pas si avec une entrée de vie réelle.


Je ne suis pas intéressant à inventer toutes sortes de scénarios qui expliqueraient ce comportement. Je vais avec celui qui s'est produit dans la réalité factuelle. L'utilisateur exécutait un programme dans un terminal.



1
votes

Le getcharner () et puchar () Les fonctions font partie du package stdio , qui fait une entrée / sortie tamponnée.

Ceci signifie que, malgré le nombre de caractères que vous demandez réellement (une seule dans votre cas), le mécanisme tampon rend les caractères à attendre dans le tampon jusqu'à un tampon entier (ou une ligne, au cas où stdin vient à partir d'un périphérique TTY) est rempli.

Qu'est-ce qui se passe ici est que, sur le premier getchar () Un remplissage complet de tampon est demandé et rempli uniquement partiellement avec la ligne d'entrée que vous Ensuite en. Après cela, tous les appels getchar () prenez des caractères individuels du tampon, jusqu'à ce qu'il soit à vide, et à ce moment-là, un autre tampon complet est demandé.

Ceci est fabriqué pour rendre un seul traitement de charcuterie un moyen de traitement efficace. Cela arrive également sur la sortie. La fonction puchar () ne remplit que le tampon, jusqu'à ce qu'il soit complètement plein (ou si votre canal de sortie soit sur un périphérique TTY, jusqu'à ce que vous demandiez de sortir un \ n Caractère) Et quand c'est le tampon complet, le tampon complet est de sortie sur le fichier / périphérique.

En outre, le pilote de terminal dans toutes les saveurs d'UNIX, fonctionne en mode ligne, ce que signifie que jusqu'à ce que vous appuyiez sur le < Code> clé, vous n'obtenez rien d'envoi au programme. Cela vous permettra de corriger les erreurs effectuées sur la saisie, à l'aide de la touche effaçante (arrière-plan) et / ou des touches de tuerie (CNTRL-U). Ceci est simulé dans les applications de console Windows, vous aurez donc probablement besoin du périphérique de sortie en mode RAW avant de pouvoir entrer de manière basée sur un caractère.

Si vous voulez faire votre programme pour lire un personnage Un temps, vous devez contourner les tampons de stdio (via SETBUF (NULL) Appel de fonction, ou à l'aide de l'appel Lecture (2) appel du système pour lire un caractère, qui peut être fait avec: xxx

) et pour mettre le pilote de terminal en mode brut (via tcsetattr () et tcgetattr () Appels, voir TERMIOS (4) Page manuelle pour plus de détails sur la façon de faire cela) Avant de faire la lecture réelle. Dans ce cas, vous devez retourner l'état du terminal en mode ligne avant de terminer le programme, ou vous rencontrerez des ennuis.


0 commentaires