Tracking User Input Using an Array

Dec 13, 2021 at 5:36pm
This is my code for using an array to track user input into a menu switch and sending the data to a .txt outfile. Thank you to all of those who helped with this. Hope it helps someone else.

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <cstdlib>      
#include <fstream>      
#include <iostream>     
#include <iomanip>      
#include <string>       
#include <ctime>        

using namespace std;

int main()
{

char tempChar = ' ';
int num; 
int choices = 0;
int optionNum [10];
string optionNam [10];
ofstream outFile2;
outFile2.open("menuLog.txt");

do
  {
    cout <<"1) Sample Function to Square a Value" << endl;
    cout <<"2) Project 1.0 - Weekly Salary" << endl;
    // More menu options 3-8
    cout <<"99) End Program" << endl;

    cout << endl << endl << "Enter a Menu Option --> ";
    if(!(cin >> num))
        {
		cin.clear();
		cin.ignore(10000, '\n');
        }

    switch (num)
  
    {
        case 1:
            optionNum[choices] = 1;
            optionNam[choices] = "Sample Function to Square a Value";
               {
            break;
               }
               
        case 2:
            optionNum[choices] = 2;
            optionNam[choices] = "Project 1.0 - Weekly Salary";
            {
            break;
            }

        // cont'd cases 3-8...
        
        case 99:
            optionNum[choices] = 99;
            optionNam[choices] = "Exit Program";
            return 0;

        default:
            optionNum[choices] = 0;
            optionNam[choices] = "Invalid Input";
            cin.clear();
            system("cls");
            cout << endl << "Invalid entry. Please Select from the following menu options." << endl << endl;
            cout << setfill('=') << setw(75) << '=' << endl;

    } // end switch

    choices++;


  } while ((num != 99) && (choices < 10));

  for (int i=0; i<choices; ++i)

    {
        outFile2 << optionNum [i] << " ---------- " << optionNam [i] << endl;
    }

  if (choices == 10)

        {
        outFile2 << "Session Max Met ---> Exit(1)";
        }

    outFile2.close();

    if (choices == 10)
        {
        cout << endl;
        cout << "Session Max Met. Please Re-Run Program to Continue. Good Bye." << endl << endl;

            for (int i=0; i<choices; ++i)
            {
            cout << optionNum [i] << " ---------- " << optionNam [i] << endl;
            }
            
        exit(1);
        }

    else return 0;

}
Last edited on Dec 14, 2021 at 12:27am
Dec 13, 2021 at 6:25pm
What do you mean with "blocking the switch" exactly?

Be aware that std::istream::operator>>(int& val) waits ("blocks") until some input to read is available.
Last edited on Dec 13, 2021 at 6:32pm
Dec 13, 2021 at 6:36pm
So the problem is that the switch won't work until the array is full. What I am trying to do is essentially have the switch for the menu selections work as normal while just tracking the selection in a log file in the background.
Dec 13, 2021 at 6:37pm
Op probably means the switch block (of code).
Dec 13, 2021 at 6:42pm
oh.
you have a loop what reads the 10 choices then uses them after that.
don't do that, read one choice and jump on into the switch.
after reading (and possibly validating) the user choice, stuff it into the next array location
eg
cin >> choice;
array[index++] = choice;
switch(choice)
{

is the crude start to doing this.
however, NOW it will go until the user quits, and the array only has a few locations. It looks like you force quit on that currently, which is fine.
Last edited on Dec 13, 2021 at 6:44pm
Dec 13, 2021 at 6:42pm
bbailey wrote:
So the problem is that the switch won't work until the array is full

Has nothing to do with the switch block.

This loop reads 10 integers from the standard input (e.g. keyboard):

1
2
3
4
for (int o=1; o<=10; ++o)
{
    cin >> option [o];
}


Until the loop is finished, i.e. all 10 integers have been read, your program won't go on. It's that simple.

If you don't want that, change the code accordingly ;-)

Also: Your loop doesn't set option[0] at all, but does write to option[10], i.e past the end of the array !!!


As said before:
Be aware that std::istream::operator>>(int& val) waits ("blocks") until some input to read is available.

What else would you expect?
Last edited on Dec 13, 2021 at 6:54pm
Dec 13, 2021 at 6:58pm
I get what you're saying. But if I take it out of the loop then the output into the log file only stores the first menu option that the user selects. Is there a different operator that I should be using that would allow the program to run normally and just record the inputs that the user makes in the background until the program terminates?

Also it's not option [0] its option [o]. In hindsight that was a dumb variable choice so I'm going to change it to something less confusing.
Dec 13, 2021 at 7:01pm
Also it's not option [0] its option [o]. In hindsight that was a dumb variable choice so I'm going to change it to something less confusing.

Yes. But, in your code, o loops from 1 (inclusive) to 10 (inclusive). It never is 0.

At the same time, valid array indices, for an array of size 10, range from 0 (inclusive) to 9 (inclusive).

Index 10 is not valid, because it would access the 11-th element !!!
Last edited on Dec 13, 2021 at 8:18pm
Dec 13, 2021 at 7:06pm
Got it. I was trying to set my first element as 1 and last as 10. I didn't realize I was messing up my indexes. Thanks
Dec 13, 2021 at 7:22pm
bbailey wrote:
I get what you're saying. But if I take it out of the loop then the output into the log file only stores the first menu option that the user selects. Is there a different operator that I should be using that would allow the program to run normally and just record the inputs that the user makes in the background until the program terminates?


Not really. In the end, you will have to decide in which particular order you want things to happen :-)

It is not possible that things "magically" happen all at once.


Well, in theory, you could create multiple threads, which then will be running concurrently.

POSIX thread (pthread):
https://www.cs.cmu.edu/afs/cs/academic/class/15492-f07/www/pthreads.html

std::thread class:
https://www.cplusplus.com/reference/thread/thread/


But then you'll have the next "problem" to solve:

How to implement the "communication" (data exchange + synchronization) between the concurrent threads?

This is all doable, but you need some understanding of multi-threaded programming.
Last edited on Dec 13, 2021 at 8:14pm
Dec 13, 2021 at 8:03pm
Addendum:

If you are targeting only M$ Windows, so Win32 API is an option, then this function may be worth a look:
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getasynckeystate

The Linux/Unix (X.org) equivalent would probably be:
https://www.x.org/releases/X11R7.5/doc/man/man3/XkbGetState.3.html
Last edited on Dec 13, 2021 at 8:07pm
Dec 13, 2021 at 8:27pm
So I took what you said and changed my strategy for how to do what I was trying to do. The new code in my post is what I came up with but for some reason, the compound test at the end of the 'do...while' statement is not working and everything after that is being ignored as well. Not really sure why. Any ideas?
Dec 13, 2021 at 9:03pm
What exactly do you mean with that?
the compound test at the end of the 'do...while' statement is not working

It probably is working, but your condition may just not be what you had intended ;-)

I suggest you run the program in a debugger and/or add more diagnostic output to see what's going on and to pinpoint where exactly things don't go as expected. Guessing probably won't give much insight...
Last edited on Dec 13, 2021 at 11:13pm
Dec 14, 2021 at 12:26am
Got it all figured out. I needed to use the && operator in the 'do... while' function and not ||. The updated code in the post works exactly as it should.
Dec 14, 2021 at 1:58am
Nice work.
If you don't mind, next time, repost the code or the changed function or even the changed line rather than edit the original. It lets people follow the conversation better.

if you have not had this, or need a refresh:
https://byjus.com/maths/boolean-algebra/

or if its just one of "those" moments -- happens to everyone.
Dec 14, 2021 at 6:13am
Oh got it. Will definitely do that next time. This was my first post so still figuring things out. Also, I have not had boolean algebra before but I am going through the link you posted and it's extremely helpful. Thank you very much for both the posting advice and the link.
Topic archived. No new replies allowed.