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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 68, средняя оценка - 4.94
Lynx607
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
15.01.2011, 21:25     Консоль. Завершение цикла нажатием клавиши #1
В консольной программе запускается бесконечный цикл. Необходимо организовать завершение цикла при нажатии любой клавиши(или какой-л конкретной).
В 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 (), но как организовать само условие пока никаких идей. Если кто сталкивался, помогите.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
romedal
 Аватар для romedal
53 / 53 / 1
Регистрация: 18.03.2010
Сообщений: 345
Записей в блоге: 1
15.01.2011, 21:29     Консоль. Завершение цикла нажатием клавиши #2
C++
1
2
char c;
while((c=getchar())!= 'a'); //до ввода символа 'a' работает цикл
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
15.01.2011, 21:43     Консоль. Завершение цикла нажатием клавиши #3
такое нельзя сделать. Программа либо должна выполняться, либо ждать ввода, а одновременно все в консольных однопоточных приложениях сделать нельзя
либо я туплю

Добавлено через 12 минут
Цитата Сообщение от romedal Посмотреть сообщение
C++
1
while((c=getchar())!= 'a'); //до ввода символа 'a' работает цикл
но тут он будет ждать ввода все равно. И для каждой итерации цикла надо жать клавишу тогда
romedal
 Аватар для romedal
53 / 53 / 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.
Lynx607
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
17.01.2011, 11:52  [ТС]     Консоль. Завершение цикла нажатием клавиши #5
Спасибо! Но я забыл уточнить, что решить эту проблему нужно стандартными средствами - у меня под рукой нет ничего, кроме стандартного компилятора g++. Ну и текстового редактора, конечно
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
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;
}
vladislavchick
35 / 35 / 1
Регистрация: 22.05.2010
Сообщений: 107
17.01.2011, 18:20     Консоль. Завершение цикла нажатием клавиши #7
Странно. Я думал, что можно
C++
1
if (kbhit()) break;
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
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);
}
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?
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
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?
Да.
Lynx607
0 / 0 / 0
Регистрация: 18.10.2010
Сообщений: 19
19.01.2011, 10:39  [ТС]     Консоль. Завершение цикла нажатием клавиши #11
Прога работает почти так как и задумывал. Всем спасибо!
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 и любые другие кнопки ничего не происходит. как мне реализовать задачу?
Andrej
И целого heap'а мало
 Аватар для Andrej
93 / 54 / 9
Регистрация: 31.07.2014
Сообщений: 293
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;
};
final_headshot
0 / 0 / 0
Регистрация: 16.01.2014
Сообщений: 7
19.08.2014, 20:40     Консоль. Завершение цикла нажатием клавиши #14
Andrej, да это слишком сложно. я думаю, что это можно сделать с помощью _kbhit() и _getch(), просто я упускаю какую-то мелочь
alsav22
5282 / 4801 / 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)
    }
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.08.2014, 21:32     Консоль. Завершение цикла нажатием клавиши
Еще ссылки по теме:

Нужно, чтобы консоль не ожидала нажатие клавиши, а сразу закрывалась C++
Вызов функции нажатием клавиши C++
Вывод результата нажатием клавиши "равно" C++

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

Или воспользуйтесь поиском по форуму:
final_headshot
0 / 0 / 0
Регистрация: 16.01.2014
Сообщений: 7
19.08.2014, 21:32     Консоль. Завершение цикла нажатием клавиши #16
alsav22, работает, спасибо
Yandex
Объявления
19.08.2014, 21:32     Консоль. Завершение цикла нажатием клавиши
Ответ Создать тему
Опции темы

Текущее время: 09:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru