Stop while loop with virtual key press

Hello, i've been working on a program about input and output in a .csv file.
It works, but my problem is that i cannot find a way to stop a while loop using a key press (Esc).
I tried with !GetAsyncKeyState(VK_ESCAPE) but it doesn't work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ofstream Library;
Library.open("Library.csv", ios::app);
while(!GetAsyncKeyState(VK_ESCAPE))
{
	system("cls");

	cout << "\n Title: ";
	cin >> Title;
		
	cout << "\n Author: ";
	cin >> Author;
	
	cout << "\n Genre: ";
	cin >> Genre;
		
	Library << Title << ";" << Author << ";" << Genre << "\n";
	Library.flush();
}
Library.close();
Hello Alexis94,

Something like this may work better for now:
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
#include <cctype>

char cont{};

ofstream Library;

Library.open("Library.csv", ios::app);

do
{
	system("cls");

	cout << "\n Title: ";
	cin >> Title;

	cout << "\n Author: ";
	cin >> Author;

	cout << "\n Genre: ";
	cin >> Genre;

	Library << Title << ";" << Author << ";" << Genre << "\n";
	Library.flush();

	std::cout << "\n\n Do Another (Y/N)? ";
	std::cin >> cont;

} while (std::toupper(cont) != 'N');  //  <--- Only the letter "n" or "N" will end the program.

Library.close();

Try to avoid using "system(anything)" as it is a potential problem and can be used to enter your computer.

If you will always be using Windows I have a function I can share with you to clear the screen. Let me know.

Andy
Thanks a lot Andy,

This method works, but it's not what i'm really searching for.
I'd like to break the loop not just at the end but anytime during its iterations, in this case by pressing a virtual key (Esc) or by any other method that can break a loop during a cin call.

I'm still a beginner so i don't really know if what i want to do is possible. If i'm trying to do something that is impossible let me know

Have a nice day,
Alexis
Hello Alexis94,

I do not know if it is impossible, but this is one Windows API function I do not very often and have not for awhile.

What I have found if that
1
2
while(!GetAsyncKeyState(VK_ESCAPE))
{
does not work. Somehow this function call needs to be inside the while loop.

The problem I found is that the formatted input does not recognize the "Esc" key or the "enter" key by its-self. It will accept the "enter" key is you type something before it first.

The down side of C++ is that it has no function to accept just a single key press and move on. I am comparing this to the old C "getch()" which is for the most part no longer used as not every compiles has the "conio.h" header file or supports it.

Maybe someone more use to this will have some ideas.

Andy
If you use a Microsoft compiler and don't care about compatibility have a look at the old _kbhit function.
https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/kbhit?view=vs-2019
The way to signal your loss of interest in a console program is to press ctrl-z (or ctrl-d if you're on Unix/Linux/BSD/).

This signals EOF to the input stream, and puts it into an error state.
This you can test by just doing things like if ( cin )

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
#include <string>
#include <iostream>
#include <string>
#include <cctype>
#include <limits>
using namespace std;

int main()
{
  char cont{};

  do
  {
    cout << "\n Title: ";
    string Title;
    cin >> Title;

    cout << "\n Author: ";
    string Author;
    cin >> Author;

    cout << "\n Genre: ";
    string Genre;
    cin >> Genre;

    if ( cin ) {
      cout << "Library=" << Title << ";" << Author << ";" << Genre << "\n";
      std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // skip any junk before the prompt
      std::cout << "\n\n Do Another (Y/N)? ";
      std::cin >> cont;
    }
  } while (cin && std::toupper(cont) != 'N');  //  <--- EOF or letter "n" or "N" will end the program.

  cout << "Thththat's all folks" << endl;

  return 0;
}

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
void f()
{
    string Title, Author, Genre;

    // Don't split the declaration of Library and it's initialization
    ofstream Library("Library.csv", ios::app);

    system("cls");

    // End loop with Ctrl-Z (Ctrl-D on linux)
    while (cout << "Title: ", cin >> Title)
    {
        // Or end loop by entering an empty Title
        if (Title.empty())
            break;

        cout << "Author: ";
        cin >> Author;
        
        cout << "Genre: ";
        cin >> Genre;
            
        // Don't use string literals if you really want a character literal.
        Library << Title << ';' << Author << ';' << Genre << '\n';
    }

    system("cls");

//    Avoid saying "close" by proper scoping.
//    Library.close();  // Library automatically closes when it goes out of scope
}

Last edited on
mimic of getch is challenging. Every OS has some way to do it, but c++ itself does not really.
windows should have an onkeypress event, but I do not know exactly how to tap it from a console program on current versions.
Topic archived. No new replies allowed.