2017-08-13 4 views
2
string s; 
while(getline(cin,s)){ 
    cout << "---" << endl 
    for(auto c: s) cout << int(c) << endl; 
} 
cout << "Exiting"; 

Si mon entrée est Ctrl +Z, alors j'appuyez sur ENTRÉE une fois, et mon programme quitte immédiatement.comportement Ctrl + Z dans le terminal

^Z 
Exiting 

Si j'entrer un caractère avant d'appuyer sur Ctrl + Z , je dois appuyer sur entrer deux fois, et mon programme ne sort pas.

s^Z 

--- 
115 
26 

J'avais toujours interprété Ctrl +Z comme le caractère EOF. getline continuerait jusqu'à ce qu'il atteigne ce caractère, à quel point getline teste faux et mon programme se terminerait. Je suis curieux de savoir pourquoi mon programme interprète Ctrl + Z comme le substitute character 26, selon qu'il y a un caractère précédent ou non, et pourquoi il m'a fallu appuyer deux fois sur Entrée dans le deuxième exemple?

+0

Ctrl + Z au début de la ligne est gérée par la même console Windows, mais bizarrement, c'est seulement pour un appel générique ['ReadFile'] (https://msdn.microsoft.com/en-us/library/aa365467), pas pour l'appel' ReadConsole' spécifique. Dans ce cas, la lecture renvoie 'lpNumberOfBytesRead' comme 0, ce que le runtime C/C++ interprète comme EOF. – eryksun

+0

Avoir à appuyer deux fois sur Entrée dans le second exemple est impair. Il garde le caractère SUB ("\ x1a") dans le tampon et supprime tout après, y compris la fin de ligne CRLF. S'il ne gardait pas SUB dans le résultat, il serait presque compréhensible, puisque les runtimes Windows C et C++ traitent ce caractère comme un marqueur EOF. ISTM le comportement correct ici devrait être de retourner de 'getline' avec tout ce qui a précédé SUB sur la ligne, de ne pas le garder dans le tampon et continuer à lire. – eryksun

Répondre

0

26 est le code de^Z sur votre plate-forme, et^Z est un marqueur EOF pour le terminal, c'est vrai. Les caractères avec des codes inférieurs à 32 sont des caractères de contrôle pour une plate-forme compatible ASCII, j'espère que vous le savez. 26 n'est pas un caractère de substitution, c'est un code de contrôle réel,^Z ou un caractère "bug" sont des substituts. getline lit l'entrée jusqu'à ce que EOL (fin de ligne, désigné comme CR par ASCII) ou EOF (fin de fichier, fin de flux, désigné par SUB) soit rencontré dans le flux, donc^Z est lu avec le deuxième appel getline. Ce comportement est absolument correct.

Elle est définie par la plate-forme (ou, plus précisément, par le type de terminal) si les caractères sont envoyés dans le tampon d'entrée immédiatement ou après une commande de vidage. La cause habituelle du vidage du tampon est le caractère EOL, c'est votre ENTREE (CR - Retour chariot). Tat's pourquoi le programme reçoit EOF après Enter dans votre cas. Notez que certaines plates-formes utilisent LF (saut de ligne) comme EOL, et d'autres - une paire de LF + CR. C littéral '\ n' doit être traduit correctement en marqueur EOL particulier.

Notez que vous pouvez utiliser différents delimiter:

template< class CharT, class Traits, class Allocator > 
std::basic_istream<CharT,Traits>& getline( 
     std::basic_istream<CharT,Traits>& input, 
     std::basic_string<CharT,Traits,Allocator>& str, 
     CharT delim); 
table ASCII

avec contrôle de substitution +: enter image description here