Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.65/140: Рейтинг темы: голосов - 140, средняя оценка - 4.65
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19

Консоль. Завершение цикла нажатием клавиши

15.01.2011, 21:25. Показов 30447. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В консольной программе запускается бесконечный цикл. Необходимо организовать завершение цикла при нажатии любой клавиши(или какой-л конкретной).
В C++ Builder это можно было сделать с помощью getch (). В google и на сайте ответ не нашёл, но если пришлёте ссылку на решение с объяснением буду очень признателен!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
using namespace std;
 
void func (int& c)
{
    c -= 2;
}
 
int main ()
{
    int a = 0, arg = 10, b;
    
    do
    {
        func (arg);
        cout << arg << endl;
        arg += 10;      
    }
    while (a == 0);
    
       cout << arg << endl;
 
    return 0;
}
P.S.: Когда я попытался это реализовать, программа либо ожидала ввода символа, либо выполнялась, не обращая внимания на ввод. Я подозреваю, что условие на получение символа нужно вставить в while (), но как организовать само условие пока никаких идей. Если кто сталкивался, помогите.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.01.2011, 21:25
Ответы с готовыми решениями:

Вызов функции нажатием клавиши
покажите пример вызова функции при нажатии определенной клавиши например escape (консольное приложение )

Завершение ввода нажатием клавиши
81 это же код клавиши Q, тогда почему и при нажатии PgDn завершается ввод #include &quot;stdio.h&quot; #include...

Прерывание бесконечного цикла нажатием горячей клавиши
Такое дело: надо, чтобы при нажатии на кнопку начиналась функция и выполнялась до тех пор, пока не будет нажат эскейп. Я пытаюсь...

15
 Аватар для romedal
55 / 55 / 9
Регистрация: 18.03.2010
Сообщений: 345
Записей в блоге: 1
15.01.2011, 21:29
C++
1
2
char c;
while((c=getchar())!= 'a'); //до ввода символа 'a' работает цикл
0
программист С++
 Аватар для sandye51
860 / 600 / 147
Регистрация: 19.12.2010
Сообщений: 2,014
15.01.2011, 21:43
такое нельзя сделать. Программа либо должна выполняться, либо ждать ввода, а одновременно все в консольных однопоточных приложениях сделать нельзя
либо я туплю

Добавлено через 12 минут
Цитата Сообщение от romedal Посмотреть сообщение
C++
1
while((c=getchar())!= 'a'); //до ввода символа 'a' работает цикл
но тут он будет ждать ввода все равно. И для каждой итерации цикла надо жать клавишу тогда
0
 Аватар для romedal
55 / 55 / 9
Регистрация: 18.03.2010
Сообщений: 345
Записей в блоге: 1
16.01.2011, 01:33
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>
#include <winuser.h>
#include <conio.h>
#include <iostream>
#pragma comment (lib,"user32.lib")
#pragma comment (lib,"Gdi32.lib")
using namespace std;
 
void func (int& c)
{
        c -= 2;
}
 
int main ()
{
    int a = 0, arg = 10, b;
    do
             {
                func (arg);
                cout << arg << endl;
                arg += 10;
                
       if (GetAsyncKeyState(0x1B)) { _getch();  break;}
 
              }
             while (a == 0);
        
             cout << arg << endl;
    _getch();
             return 0;
}
Добавлено через 5 минут
Забыл прокоментировать, цикл ваш завершится, как только нажмёте 'Esc' (после 2-го нажатия окно закроется)
Писал в среде MS Visual Studio 2010.
0
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
17.01.2011, 11:52  [ТС]
Спасибо! Но я забыл уточнить, что решить эту проблему нужно стандартными средствами - у меня под рукой нет ничего, кроме стандартного компилятора g++. Ну и текстового редактора, конечно
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
17.01.2011, 13:54
Цитата Сообщение от sandye51 Посмотреть сообщение
такое нельзя сделать. Программа либо должна выполняться, либо ждать ввода, а одновременно все в консольных однопоточных приложениях сделать нельзя
Это, если мануалов не читать. Вот с ncurses пример. В винде тоже не сложно делается...
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <curses.h>
 
#define DELAY 1000
 
int main(void){
    int cnt;
    
    cnt = 10;
    
    initscr();
    timeout(DELAY); 
    printw("CountDown: %d", --cnt);
    while ( getch() == ERR ){
        if ( ! cnt )
            break;
        printw("%c%d", '\b', --cnt);
    }
    endwin();
    
    printf("%s\n", ( cnt ) ? "Oh yeah! You stop it!" : "BOOM!!! Everybody dies!");
    
    return 0;
}
1
35 / 35 / 8
Регистрация: 22.05.2010
Сообщений: 107
17.01.2011, 18:20
Странно. Я думал, что можно
C++
1
if (kbhit()) break;
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
17.01.2011, 19:02
Цитата Сообщение от vladislavchick Посмотреть сообщение
Я думал, что можно
Да можно, всё можно...
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
 
int main(void){
    int cnt = 10;
    
    printf("CountDown: %d", --cnt);
    while ( ! kbhit() ){
        if ( ! cnt )
            break;
        Sleep(1000);
        printf("%c%d", '\b', --cnt);
    }
 
    printf("\n%s\n", ( cnt ) ? "You safe the world!" : "We gonna die when you sleep!");
 
    system("pause");
    exit(0);
}
0
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
17.01.2011, 19:13  [ТС]
easybudda, да, это работает. Только сначала нужно:
1. Установить ncurses( можно вот отсюда http://www.gnu.org/software/ncurses/ncurses.html).
2. Добавить заголовок #include <ncurses.h>.
3. Компилировать g++ ios.cpp -l ncurses -o test(т.е. при компиляции подключить библиотеку)

Только когда я использовал это в своей программе
C++
1
2
3
4
5
6
7
8
9
10
11
12
...
    initscr();
        timeout(delay); 
        do
    {
        func (arg);
        cout << arg << endl;
        arg += 10;      
    }
    while(getch() == ERR);
    endwin();
...
, вывод происходит следующим образом:
C++
1
2
3
4
5
16
    24  
         32
             40
...
Т.е. при получении endl ncurses переводит курсор на новую строку в ту позицию, на которой он остановился до endl.
Можете подсказать как сделать вывод каждого числа с начала строки?


vladislavchick, для использования этой функции, нужно подключить "conio.h". Как я понял, под linux его нет
easybudda, я правильно понимаю, что последний ваш вариант только для windows?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
17.01.2011, 21:05
Цитата Сообщение от Lynx607 Посмотреть сообщение
1. Установить ncurses
В *NIX системах ncurses или уже стоит, или в две секунды устанавливается из портов/пакетов/etc...
Цитата Сообщение от Lynx607 Посмотреть сообщение
2. Добавить заголовок #include <ncurses.h>
С этим сложнее... В MacOS оно <curses.h>, в CygWin <ncurses/curses.h>
Цитата Сообщение от Lynx607 Посмотреть сообщение
вывод происходит следующим образом
Ну я-то printw использовал - она для работы с ncurses как-то уместнее по-моему...
Цитата Сообщение от Lynx607 Посмотреть сообщение
я правильно понимаю, что последний ваш вариант только для windows?
Да.
0
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
19.01.2011, 10:39  [ТС]
Прога работает почти так как и задумывал. Всем спасибо!
0
0 / 0 / 0
Регистрация: 16.01.2014
Сообщений: 7
19.08.2014, 17:47
Помогите разобраться с ошибкой. Есть прога, которая считает количество файлов в папке и всех её внутренних папках. основная функция работает, но нужно чтобы в процессе подсчета файлов можно было нажать ESC и тогда подсчет остановился, а на экран вывелся текущий результат. я могу это сделать, но только для нажатия любой кнопки, а не конкретно ESC.
Определение функций:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include "stdafx.h"
#include <string>
#include <io.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <conio.h>
using namespace std;
 
#include "folder.h"
 
Folder::Folder (string& w, int n):way(w), files(0), number(n)
{
}
 
int Folder::countf()
{
  struct _finddata_t info;
  intptr_t seek;   
  seek = _findfirst((way + "\\*").c_str(), &info); 
  if (seek == -1) return 0; //если в текущей папке ничего нет, возвращает ноль
  else
  {
    //два раза выполнение функции _findnext для пропуска папок "." и ".." 
    _findnext(seek, &info);
    _findnext(seek, &info);     
    //выполнять пока не закончатся файлы и папки или не будет нажата кнопка
    do
    {
      if (info.attrib==_A_SUBDIR)
      {     
        Folder *f = new Folder((way + "\\" +info.name), 0);
        files+=f->countf();
        delete f;       
      }   
      else if (info.attrib!=_A_SUBDIR)
      {
        files++;
      }       
      if (_kbhit())
      {
        return files;
      }
    }while (_findnext(seek, &info)==0);     
  }
  return files;
}
 
void Folder::print ()
{
  cout<<left<<setw(2)<<number<<setw(10)<<files<<" "<<setw(100)<<way<<endl;
}
 
void Folder::write (ofstream &of)
{
  of<<way<<"; "<<files<<endl;
}
основная программа:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "stdafx.h"
#include <string>
#include <fstream>
#include <iostream>
#include <conio.h>
#include "folder.h"
 
using namespace std;
 
 
int main(int argc, char* argv[])
{
  setlocale(LC_ALL, "Russian");
  string path;
  int i=1;
  ifstream PathFile(argv[1], ios::in);
  ofstream ResultFile(argv[2], ios::out);
  while (!PathFile.eof())
  {
    getline(PathFile, path);
    Folder *f = new Folder(path, i);
    f->countf();    
    if (!_kbhit()) 
    {
      f->print();
      f->write(ResultFile);
    }
    else 
    {
      cout<<"Выполнение прервано"<<endl;
      f->print();
      break;
    }
    i++;
  } 
  system("pause");
  return 0;
}
проверка нажатия клавиши происходит в функции countf(). если я заменю :
в определении countf() строки 40-43
C++
1
2
3
4
5
if (_kbhit())
      {
        if (_getch()==27)
          return files;
      }
в главном файле строки 23-33:

C++
1
2
3
4
5
6
7
8
9
10
11
if (!(_kbhit()&&_getch()==27)) 
    {
      f->print();
      f->write(ResultFile);
    }
    else 
    {
      cout<<"Выполнение прервано"<<endl;
      f->print();
      break;
    }
при нажатии на ESC и любые другие кнопки ничего не происходит. как мне реализовать задачу?
0
И целого heap'а мало
 Аватар для Andrej
96 / 57 / 17
Регистрация: 31.07.2014
Сообщений: 291
19.08.2014, 19:49
Можно попробовать обработчики сигналов навесить
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template <typename Signaled>
class SignalsHandler {
public: /* methods: */
    SignalsHandler(Signaled& signaled)
    {
        this->signaled = &signaled;
        std::signal(SIGINT, this->handle);
        std::signal(SIGTERM, this->handle);
#if defined(WIN32)
        std::signal(SIGBREAK, [](int sig) -> void
                                           {
                                                FreeConsole();
                                           });
# endif
    };
 
    static void
    handle(int signal)
    {
        if (signaled) {
            signaled->stopOnSignal();
        }
    };
private: /* fields: */
    static Signaled* signaled;
};
0
0 / 0 / 0
Регистрация: 16.01.2014
Сообщений: 7
19.08.2014, 20:40
Andrej, да это слишком сложно. я думаю, что это можно сделать с помощью _kbhit() и _getch(), просто я упускаю какую-то мелочь
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
19.08.2014, 21:13
Если так:
C++
1
2
3
4
5
6
7
8
9
10
11
    if (_kbhit() && (_getch() == 27)) 
    {
      cout<<"Выполнение прервано"<<endl;
      f->print();
      break;
    }
    else 
    {
      f->print();
      f->write(ResultFile)
    }
1
0 / 0 / 0
Регистрация: 16.01.2014
Сообщений: 7
19.08.2014, 21:32
alsav22, работает, спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.08.2014, 21:32
Помогаю со студенческими работами здесь

Завершение цикла при нажатии клавиши
Проигрывается звуковой файл зацикленно, пока не нажата любая клавиша. var q:string; const fname = 'tadamm1.wav'; ...

Есть ли возможность реализовать прерывание цикла консольного приложения нажатием клавиши?
Выполняется цикл, при нажатии клавиши (например &quot;А&quot;) цикл прерывается, но программа не закрывается. Приложение консольное

Завершение работы функции повторным нажатием горячих клавиш
При нажатии ALT + A начинает бесконечно работать функция. По идее, если нажать второй раз ALT + A, то функция должна прерваться, но как это...

Остановка программы нажатием клавиши
Как сделать так чтобы движение фигуры останавливалось после нажатия какой-нибудь клавиши? SCREEN 12 FOR x = 1 TO 500 LOCATE 14,...

Убить процесс нажатием клавиши
Помогите, пожалуйста, реализовать программу, которая запускается и ждет нажатия комбинации клавиш. То есть, например, я нахожусь в игре,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20%
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
Уведомление о неверно выбранном значении справочника
Maks 06.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "НарядПутевка", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если в документе выбран неверный склад. . .
Установка Qt Creator для C и C++: ставим среду, CMake и MinGW без фреймворка Qt
8Observer8 05.04.2026
Среду разработки Qt Creator можно установить без фреймворка Qt. Есть отдельный репозиторий для этой среды: https:/ / github. com/ qt-creator/ qt-creator, где можно скачать установщик, на вкладке Releases:. . .
AkelPad-скрипты, структуры, и немного лирики..
testuser2 05.04.2026
Такая программа, как AkelPad существует уже давно, и также давно существуют скрипты под нее. Тем не менее, прога живет, периодически что-то не спеша дополняется, улучшается. Что меня в первую очередь. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru