Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 68, средняя оценка - 4.94
Lynx607
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
#1

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

15.01.2011, 21:25. Просмотров 10025. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.01.2011, 21:25
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Консоль. Завершение цикла нажатием клавиши (C++):

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

Нужно закончить ввод последовательности чисел нажатием клавиши ENTER - C++
В общем есть цикл for, в нем мы вводим последовательно числа. char a; int i; For (i=0; i&lt;9; i++) { if (cin.getline(a, 9,...

Досрочное завершение цикла for - C++
for (int i = 0; i &lt; n; i++) { cin &gt;&gt; names &gt;&gt; scores; } // прекратить ввод введение строки No More если даже i не достиг...

Завершение цикла при вводе EOF - C++
Пишу небольшую программку и в ней имеется вот такой код: typedef std::istream_iterator&lt;std::string&gt; string_input; for...

Условие завершение цикла с использованием структуры - C++
Доброе время суток! Я новичок на этом форуме и если че не так не ругайтесь. У меня такой вопрос как задать условие выхода из цикла....

Завершение бесконечного цикла через определенное время - C++
Есть бесконечный цикл for( ; ; ), который обрабатывает событие нажатия кнопки в игре. Если на кнопку не нажали в течении двух секунд,...

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

Добавлено через 12 минут
Цитата Сообщение от romedal Посмотреть сообщение
C++
1
while((c=getchar())!= 'a'); //до ввода символа 'a' работает цикл
но тут он будет ждать ввода все равно. И для каждой итерации цикла надо жать клавишу тогда
0
romedal
54 / 54 / 1
Регистрация: 18.03.2010
Сообщений: 345
Записей в блоге: 1
16.01.2011, 01:33 #4
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
Lynx607
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
17.01.2011, 11:52  [ТС] #5
Спасибо! Но я забыл уточнить, что решить эту проблему нужно стандартными средствами - у меня под рукой нет ничего, кроме стандартного компилятора g++. Ну и текстового редактора, конечно
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,778
17.01.2011, 13:54 #6
Цитата Сообщение от 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
vladislavchick
35 / 35 / 1
Регистрация: 22.05.2010
Сообщений: 107
17.01.2011, 18:20 #7
Странно. Я думал, что можно
C++
1
if (kbhit()) break;
0
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,778
17.01.2011, 19:02 #8
Цитата Сообщение от 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
Lynx607
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
17.01.2011, 19:13  [ТС] #9
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
easybudda
Модератор
Эксперт CЭксперт С++
9664 / 5614 / 952
Регистрация: 25.07.2009
Сообщений: 10,778
17.01.2011, 21:05 #10
Цитата Сообщение от Lynx607 Посмотреть сообщение
1. Установить ncurses
В *NIX системах ncurses или уже стоит, или в две секунды устанавливается из портов/пакетов/etc...
Цитата Сообщение от Lynx607 Посмотреть сообщение
2. Добавить заголовок #include <ncurses.h>
С этим сложнее... В MacOS оно <curses.h>, в CygWin <ncurses/curses.h>
Цитата Сообщение от Lynx607 Посмотреть сообщение
вывод происходит следующим образом
Ну я-то printw использовал - она для работы с ncurses как-то уместнее по-моему...
Цитата Сообщение от Lynx607 Посмотреть сообщение
я правильно понимаю, что последний ваш вариант только для windows?
Да.
0
Lynx607
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
19.01.2011, 10:39  [ТС] #11
Прога работает почти так как и задумывал. Всем спасибо!
0
final_headshot
0 / 0 / 0
Регистрация: 16.01.2014
Сообщений: 7
19.08.2014, 17:47 #12
Помогите разобраться с ошибкой. Есть прога, которая считает количество файлов в папке и всех её внутренних папках. основная функция работает, но нужно чтобы в процессе подсчета файлов можно было нажать 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
Andrej
И целого heap'а мало
94 / 55 / 9
Регистрация: 31.07.2014
Сообщений: 291
19.08.2014, 19:49 #13
Можно попробовать обработчики сигналов навесить
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
final_headshot
0 / 0 / 0
Регистрация: 16.01.2014
Сообщений: 7
19.08.2014, 20:40 #14
Andrej, да это слишком сложно. я думаю, что это можно сделать с помощью _kbhit() и _getch(), просто я упускаю какую-то мелочь
0
alsav22
5421 / 4816 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
19.08.2014, 21:13 #15
Если так:
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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.08.2014, 21:13
Привет! Вот еще темы с ответами:

Цикл: Выйти в любой момент времени из цикла while нажатием определённой кнопки. Как реализовать? - C++
Необходимо выйти в любой момент времени из цикла while нажатием определённой кнопки. Как реализовать?

Вывод результата нажатием клавиши "равно" - C++
как отобразить результат нажатием кнопки '=' ? (Пример: 2 + 4 = результат) #include &lt;iostream&gt; using namespace std; int main() { ...

крестики нолики- консоль + клавиши + символьное оформление - C++
здраствуйте,неполучается на данном етапе,организовать отображение рамок - │ символов и неполучается,точнее странно происходит при...

Нужно, чтобы консоль не ожидала нажатие клавиши, а сразу закрывалась - C++
Может это прозвучит глупо, но мне надо чтобы консоль не ожидала нажатие клавиши, а сразу закрывалась. Ни getch() ни system(&quot;pause&quot;) я не...


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

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
19.08.2014, 21:13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru