Есть ли приличная функция ожидания в C ++? - PullRequest
43 голосов
/ 23 мая 2009

Первое, что я узнал в C ++, было то, что

#include <iostream>
int main()
{
    std::cout<<"Hello, World!\n";
    return 0;
}

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

helloworld.exe
pause

аза

helloworld.bat

Это было утомительно, когда мне нужно было создать кучу небольших тестовых программ, и в конце концов я просто поставил while(true); в конце большинства моих тестовых программ, чтобы я мог видеть результаты. Есть ли лучшая функция ожидания, которую я могу использовать?

Ответы [ 14 ]

60 голосов
/ 23 мая 2009

вы можете потребовать, чтобы пользователь нажал клавишу ввода перед закрытием программы ... что-то вроде этого работает.

#include <iostream>
int main()
{
  std::cout << "Hello, World\n";
  std::cin.ignore();
  return 0;
}

Cin читает пользовательский ввод, а функция .ignore () cin сообщает программе просто игнорировать ввод. Программа продолжится, как только пользователь нажмет ввод.

Ссылка

45 голосов
/ 02 апреля 2016

Многие люди предложили POSIX sleep, Windows Sleep, Windows system("pause"), C ++ cin.get() & hellip; там даже DOS getch(), примерно с конца 1920-х годов.

Пожалуйста, не делайте ничего из этого.

Ни одно из этих решений не прошло бы проверку кода в моей команде. Это означает, что если вы отправите этот код для включения в наши продукты, ваша фиксация будет заблокирована, и вам будет предложено пойти и найти другое решение. (Кто-то может возразить, что все не так серьезно, когда вы просто любите играть, но я предлагаю, чтобы развитие хороших привычек в ваших любимых проектах сделало вас ценным профессионалом в бизнес-организации и вас наняли. )

Сохранение открытого окна консоли, чтобы вы могли прочитать вывод вашей программы, не - ответственность вашей программы! Когда вы добавляете wait / sleep / block в конец вашей программы, вы нарушаете принцип единой ответственности, создавая большую утечку абстракции и уничтожая возможность повторного использования / цепочки вашей программы. Он больше не принимает входные данные и выдает выходные данные & mdash; это блокирует по временным причинам использования. Это очень нехорошо.

Вместо этого вам следует настроить среду , чтобы оставить приглашение открытым после того, как ваша программа закончит свою работу. Хороший подход - обертка Batch-скрипта! Я вижу, как досадно постоянно обновлять вручную, и вы не можете вызвать его из IDE. Вы можете заставить скрипт взять путь к программе для выполнения в качестве параметра и настроить IDE так, чтобы он вызывался вместо вашей программы напрямую.

Промежуточный подход быстрого запуска: изменить команду запуска вашей IDE с cmd.exe <myprogram> или <myprogram> на cmd.exe /K <myprogram>. Переключатель /K на cmd.exe заставляет приглашение оставаться открытым после завершения программы по указанному пути . Это будет немного более раздражающим, чем ваше решение Batch-скрипта, потому что теперь вам нужно набрать exit или нажать на красный 'X', когда вы закончите читать вывод вашей программы, а не просто чмокать пробел.


Я предполагаю использование IDE, потому что иначе вы уже вызываете из командной строки, и это не было бы проблемой в первую очередь. Кроме того, я предполагаю использование Windows (основываясь на деталях, приведенных в вопросе), но этот ответ относится к любой платформе & hellip; что, впрочем, половина пункта.

44 голосов
/ 20 февраля 2013

Обратите внимание, что приведенный выше код был протестирован на Code :: Blocks 12.11 и Visual Studio 2012
в Windows 7.

Для принудительного завершения или ожидания вашей программы у вас есть несколько вариантов:


  • сон (без знака int)

Значение должно быть положительным целым числом в миллисекундах. Это означает, что если вы хотите, чтобы ваша программа ждала 2 секунды, введите 2000.

Вот пример:

#include <iostream>     //for using cout
#include <stdlib.h>     //for using the function sleep

using namespace std;    //for using cout

int main(void)         
{
   cout << "test" << endl;
   sleep(5000);         //make the programme waiting for 5 seconds
   cout << "test" << endl;
   sleep(2000);         // wait for 2 seconds before closing

   return 0;
}

Если вы ждете слишком долго, это, вероятно, означает, что параметр в секундах. Так что измените это на:

sleep(5);

Для тех, кто получает сообщение об ошибке или проблему с использованием сна, попробуйте заменить его на _sleep или Sleep, особенно в Code :: Bloks. И если у вас все еще возникают проблемы, попробуйте добавить одну эту библиотеку в начале кода.

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <dos.h>
#include <windows.h>

  • система ( "PAUSE")

Простая программа "Hello world" в консольном приложении Windows, вероятно, закроется, прежде чем вы сможете что-либо увидеть. Это тот случай, когда вы можете использовать систему («Пауза»).

#include <iostream>    

using namespace std;   

int main(void)         
{
    cout << "Hello world!" << endl;

    system("PAUSE");

    return 0;
}

Если вы получили сообщение «ошибка:« система »не была объявлена ​​в этой области», просто добавьте следующая строка в начале кода:

#include <cstdlib>

  • cin.ignore ()

Тот же результат может быть достигнут с помощью cin.ignore ():

#include <iostream>     

using namespace std;    

int main(void)         
{
    cout << "Hello world!" << endl;

    cin.ignore();

    return 0;
}

  • cin.get ()

пример:

#include <iostream>     

using namespace std;    

int main(void)         
{
    cout << "Hello world!" << endl;

    cin.get();

    return 0;
}

  • Геч ()

Только не забудьте добавить библиотеку conio.h:

#include <iostream>     
#include <conio.h>    //for using the function getch()

using namespace std;    

int main(void)
{

    cout << "Hello world!" << endl;

    getch();

    return 0;
}

Вы можете получить сообщение о том, что вы должны использовать _getch () вместо getch

20 голосов
/ 24 мая 2009

Появление и исчезновение окна для отображения текста - это особенность того, как вы запускаете программу, а не C ++.

Запускать в постоянной среде командной строки или включать поддержку окон в вашей программы, либо использовать sleep, либо ждать ввода, как показано в других ответах.

12 голосов
/ 23 мая 2009

эквивалент пакетной программы будет

#include<iostream>
int main()
{
    std::cout<<"Hello, World!\n";
    std::cin.get();
    return 0;
}

Дополнительная строка делает именно то, что делает PAUSE, ожидает ввода одного символа

7 голосов
/ 17 октября 2015

На самом деле, вопреки другим ответам, я считаю, что решение OP является наиболее элегантным.

Вот что вы получаете, используя внешнюю .bat оболочку:

  1. Приложение явно ожидает ввода пользователя, поэтому оно уже делает то, что вы хотите.
  2. Вы не загромождаете код неловкими звонками. Кто должен ждать? main()
  3. Вам не нужно разбираться с кроссплатформенными проблемами - посмотрите, сколько людей предложили system("pause") здесь.
  4. Без этого для автоматического тестирования вашего исполняемого файла в модели тестирования черного ящика вам необходимо смоделировать нажатие клавиши enter (если вы не выполните действия, указанные в сноске).
  5. Возможно, самое главное - если любой пользователь захочет запустить ваше приложение через терминал (cmd.exe на платформе Windows), он не не хочет ждать, так как он все равно увидит вывод. С помощью метода оболочки .bat они могут решить, запустить ли оболочку .bat (или .sh) или запустить исполняемый файл напрямую.

Сосредоточив внимание на последних двух точках - с любой другой техникой я бы ожидал, что программа предложит по крайней мере --no-wait переключатель, чтобы я, как пользователь, мог использовать приложение со всеми видами операций, такими как конвейерная передача вывод, связывание его с другими программами и т. д. Это часть обычного рабочего процесса CLI, и добавление ожидания в конце, когда вы уже находитесь внутри терминала, просто мешает работе и разрушает взаимодействие с пользователем.

По этим причинам решение IMO .bat здесь самое хорошее.

5 голосов
/ 05 февраля 2017

Существует C ++ 11 способ сделать это. Это довольно просто, и я считаю, что это портативный. Конечно, как указывало Lightness Races на орбите , вы не должны делать это, чтобы иметь возможность видеть Hello World в своем терминале, но есть некоторые веские причины для использования функция ожидания. Без лишних слов,

#include <chrono> // std::chrono::microseconds
#include <thread> // std::this_thread::sleep_for;
std::this_thread::sleep_for(std::chrono::microseconds{});

Более подробная информация доступна здесь . Смотрите также sleep_until .

3 голосов
/ 24 мая 2009

То, что у вас есть, можно написать проще. Вместо:

#include<iostream>
int main()
{
    std::cout<<"Hello, World!\n";
    return 0;
}

запись

#include<iostream>
int main()
{
    std::cout<<"Hello, World!\n";
    system("PAUSE");
    return 0;
}

Системная функция выполняет все, что вы ей даете, как если бы оно было записано в командной строке. Он приостанавливает выполнение вашей программы во время выполнения команды, поэтому вы можете делать с ней все, что угодно, даже компилировать программы из вашей программы cpp.

2 голосов
/ 23 мая 2009

Синтаксис:

недействительный сон (без знака секунды);

sleep () приостанавливает выполнение на некоторый интервал (секунды). При обращении к режиму ожидания текущая программа приостанавливается на выполнение на количество секунд, указанное в аргументе секунд. Интервал является точным только с точностью до одной сотой секунды или с точностью тактовой частоты операционной системы, в зависимости от того, что меньше.

Этот пример должен прояснить:

#include <dos.h>
#include <stdio.h>
#include <conio.h>

int main()
{
   printf("Message 1\n");
   sleep(2); //Parameter in sleep is in seconds
   printf("Message 2 a two seconds after Message 1");
   return 0;
}

Помните, что вы должны #include dos.h

EDIT:

Вы также можете использовать winAPI.

VOID WINAPI Sleep(
DWORD dwMilliseconds
);

Функция сна (Windows)

Просто обратите внимание, параметр в функции, предоставляемой winapi, указывается в миллисекундах, поэтому строка сна в приведенном выше фрагменте кода будет выглядеть так: «Sleep (2000);»

0 голосов
/ 10 февраля 2013

Перед выпиской о возврате в главном введите этот код:

система ( "пауза");

Это будет удерживать консоль, пока вы не нажмете клавишу.

#include<iostream>
#include<string>

using namespace std;

int main()
{
    string s;
    cout << "Please enter your first name followed by a newline\n";
    cin >> s;
    cout << "Hello, " << s << '\n';
    system("pause");
    return 0; // this return statement isn't necessary
}
...