Ctrl-Z produces EOF, which is then read by cin. When an istream reads EOF it sets its fail flag to true, hence cin.fail() returns true and your loop stops. I really don't know why people have had so much trouble explaining this.