read () de stdin
Considérer la ligne de code suivante:
while((n = read(STDIN_FILENO, buff, BUFSIZ)) > 0)
Selon ma compréhension read/write
fonctions sont une partie de la non-tampon d'e/s. cela veut-il dire read()
fonction va lire qu'un seul personnage par appel d'stdio? Ou en d'autres termes, la valeur de n sera
-1 in case of error
n = 0 in case of EOF
1 otherwise
Si ce n'est pas le cas, quand le ci-dessus read()
fonction sera de retour et pourquoi?
Note: je me disais aussi que read()
va attendre jusqu'à ce qu'il lit correctement BUFSIZ
nombre de caractères à partir de stdin. Mais ce qui se passe dans un cas nombre de caractères disponible à la lecture, sont à moins de BUFSIZ
? Va lire attendre indéfiniment ou jusqu'à ce que EOF arrive (Ctrl + D
sur unix ou Ctrl + Z
sur windows)?
Aussi, disons BUFSIZ = 100
et stdin = ACtrl+D
(j'.e EOF immédiatement à la suite d'un seul caractère). Maintenant, combien de fois le while loop
va se répéter?
source d'informationauteur Ravi Gupta
Vous devez vous connecter pour publier un commentaire.
La façon de lire() se comporte dépend de ce qui est en cours de lecture. Pour les fichiers réguliers, si vous demandez à N caractères, vous bénéficiez de N caractères s'ils sont disponibles, à moins de N si la fin du fichier intervient.
Si read() lecture à partir d'un terminal dans canonique/cuit mode, le pilote tty fournit des données d'une ligne à la fois. Alors, si vous dites read() pour obtenir 3 caractères ou de 300, la lecture se bloque jusqu'à ce que le pilote tty a vu un retour à la ligne ou le terminal est défini EOF clé, puis de les lire() sera de retour avec le nombre de caractères dans la ligne ou le nombre de caractères que vous avez demandé, selon le moindre des deux.
Si read() lecture à partir d'un terminal non-canonique/mode raw, lire auront accès à des combinaisons de touches immédiatement. Si vous demandez à la lecture() pour obtenir 3 caractères, elle peut revenir à n'importe où de 0 à 3 caractères en fonction de synchronisation d'entrée et de la façon dont le terminal est configuré.
read() va se comporter différemment dans le visage de signaux, de retour à moins que le requérant nombre de caractères, ou -1 avec errno à EINTR si un signal interrompu le lire avant tout les personnages sont arrivés.
read() se comporte différemment si le descripteur a été configuré pour les non-blocage I/O. read() renvoie -1 avec errno à EAGAIN ou EWOULDBLOCK si aucune entrée n'était immédiatement disponible. Cela s'applique aux sockets.
Donc, comme vous pouvez le voir, vous devriez être prêt pour les surprises lorsque vous appelez la fonction read(). Vous n'obtiendrez pas toujours le nombre de caractères que vous avez demandé, et vous pouvez obtenir des erreurs non fatales comme EINTR, ce qui signifie que vous doit recommencer la lecture().
Votre code se lit comme suit:
C'est imparfait - les parenthèses signifient qu'il est interprété comme:
où la condition booléenne est évaluée avant la cession, afin de
n
obtiendra uniquement les valeurs 0 (la condition n'est pas vrai) et 1 (la condition est vraie).Vous devriez écrire:
Cela s'arrête sur les expressions du FOLKLORE ou d'une erreur de lecture, et
n
vous permet de savoir quelle condition vous avez rencontré.Apparemment, le code ci-dessus était une faute de frappe dans la question.
Sans tampon I/O va lire le nombre de caractères à vous lire (mais pas plus). Il peut lire de moins en moins sur le compte des expressions du FOLKLORE ou d'une erreur. Il peut également lire moins parce que moins est disponible au moment de l'appel. Envisager un terminal; en général, qui ne fera que lire jusqu'à la fin de la ligne, car il n'y a pas plus que ce que. Envisager un tuyau; si le processus d'alimentation a généré 128 octets lus, alors si BUFSIZ est de 4096, vous obtiendrez seulement 128 octets à partir de la lecture. Un non-bloquant descripteur de fichier peut retourner parce que rien n'est disponible; un socket peut revenir moins d'octets, car il n'y a pas plus d'informations disponibles; une lecture du disque peut revenir moins d'octets parce qu'il y a de moins en moins que le nombre d'octets dans le fichier lorsque la lecture est effectuée.
En général, cependant,
read()
ne renvoie pas seulement à un seul octet si vous demandez combien d'octets.Comme le
read()
page de manuel états:Ainsi, chaque
read()
va lire jusqu'à le nombre d'octets spécifié; mais il peut lire moins. "Non tamponnée" signifie que si vous spécifiezread(fd, bar, 1)
lecture seulement lecture d'un octet. Tampon IO tente de lire dans les quanta deBUFSIZ
même si vous voulez seulement un caractère. Cela peut sembler inutile, mais il évite la surcharge d'appels système, ce qui le rend rapide.après avoir fait cela la lecture suivante renvoie -1, pour vous signaler que la fin du fichier.
Ce qui se passe quand on essaie de lire et il n'en est rien, il s'agit de quelque chose appelé le blocage. Vous pouvez appeler l'ouvrir pour lire un fichier bloquant ou non bloquant. "blocage" signifie attendre jusqu'à ce que il ya quelque chose pour revenir.
C'est ce que vous voyez dans un shell en attente d'entrée. Il y est assis. Jusqu'à ce que vous appuyez sur return.
Non-blocage signifie que la lecture de retour n octets de données si on n'y fait. En fonction de beaucoup d'autres facteurs qui pourraient avoir une réponse correcte inutilisable pour vous, la lecture de errno contient quelque chose comme EWOULDBLOCK, qui vous permet de savoir pourquoi votre lecture retourné zéro octets. Il n'est pas nécessairement une erreur fatale.
Votre code de test pour un moins pour trouver des expressions du FOLKLORE ou des erreurs
Quand nous disons
read
est non, cela signifie pas de mise en mémoire tampon au niveau de votre processus d'après les données est retiré de la sous-tendent la description du fichier ouvert, qui est potentiellement un-ressource partagée. Sistdin
est un terminal, il y a probablement au moins 2 coussins de fonds propres supplémentaires dans le jeu, cependant:read
va tirer de ce qui a déjà été soumis, au max de lire la longueur de votre passé, mais il est impossible de tirer quoi que ce soit à partir de la ligne de mémoire tampon d'édition. Si vous souhaitez désactiver cette couche supplémentaire de mise en mémoire tampon, vous avez besoin pour la recherche de la façon de désactiver cuit/mode canonique d'un terminal à l'aide detcsetattr
etc.