Инструкция C переупорядочивается, когда cin cout и gets используется последовательно - PullRequest
1 голос
/ 24 февраля 2011

Кто-нибудь знает, почему инструкция C переупорядочивается, когда cin cout и gets используется здесь последовательно?Я использую Dev-C ++ 4.9.9.2.

#include<iostream>
using namespace std;

int main(){
    char a[10],b;
    for(;;){
        cout<<"\ncin>>b:";
        cin>>b;
        cout<<"gets(a):";
        gets(a);
        cout<<"cout<<a<<b:"<<a<<" "<<b<<"\n\n";
    }
}

Я получил вывод вроде:

cin>>b:132
gets(a):cout<<a<<b:32 1


cin>>b:465
gets(a):cout<<a<<b:65 4


cin>>b:312242
gets(a):cout<<a<<b:12242 3


cin>>b:1
gets(a):cout<<a<<b: 1

cin>>b:

Казалось, что некоторый вход для cin был передан в get ...Похоже, что инструкции были переупорядочены следующим образом:

cin>>b;
gets(a);
cout<<"gets(a):";

вместо

cin>>b;
cout<<"gets(a):";
gets(a);

Ответы [ 4 ]

2 голосов
/ 24 февраля 2011

cin >> b читает только символ, оставляя оставшуюся часть ввода для последующей операции ввода. Так что получает подоконник, есть что почитать и не блокировать.

В первом cin >> b вход недоступен. Вы вводите «132 \ n» (ввод с терминала обычно делается построчно) в буфере и просто получаете 1 из него. получает читает следующие символы 32 и \ n, который завершается получает. Не нужно читать что-то еще из терминала.

0 голосов
/ 24 февраля 2011

Код не переупорядочен, но std :: cout буферизован, поэтому строка не появляется сразу на вашем дисплее. Следовательно, get (a) будет выполняться с выводом в буфере.

Вы можете добавить << flush после выходной строки, чтобы cout сбрасывал ее буфер. </p>

Когда вы используете std :: cin, он знает, как сказать std :: cout очистить буфер перед началом ввода, так что вам не нужно.

0 голосов
/ 24 февраля 2011

Пока на самом деле не отвечаю на ваш вопрос ...

Идиоматический способ в C ++ - использовать getline . Это случайность истории, которая не делает его частью интерфейса iostream напрямую, но на самом деле это функция , используемая для ввода.

Бесстыдная заглушка с сайта:

// getline with strings
#include <iostream>
#include <string>

int main () {
  std::string str;
  std::cout << "Please enter full name: ";
  getline (std::cin,str);
  std::cout << "Thank you, " << str << ".\n";
}

Основным преимуществом getline в этой версии является то, что он читает до тех пор, пока не встретит символ конца строки.

Вы можете указать свой собственный набор символов "конца строки" в перегрузке, принимая третий параметр, например, чтобы он останавливался на запятых или двоеточиях.

0 голосов
/ 24 февраля 2011

Ничего не было переупорядочено.

ваш ввод с клавиатуры отправлялся только при нажатии клавиши ввода. В то время было достаточно данных для выполнения cin<<b, следующего cout, а затем для завершения gets(a).

Другими словами, исполнение cin<<b приостанавливается до получения символа. Но этот символ не отправляется в программу, пока вы не нажмете «Enter» (это из-за настроек вашего терминала). Когда вы нажимаете «Enter», первый символ получает cin<<b, а оставшийся буферизируется. cout выполняется, и когда наступает черед gets(a), буфер доставляет оставшиеся символы, включая возврат каретки, поэтому gets(a) также завершается с данными, введенными вами для выполнения инструкции cin<<b.

Попробуйте просто нажать Enter для завершения cin<<b, затем вы увидите cout, и тогда у вас будет gets(a), ожидающий ваших входных данных.

...