Archived

This topic is now archived and is closed to further replies.

kuphryn

Command Line (cin) Hiding & Counter Using C++

Recommended Posts

kuphryn    210
Hi. I was wondering how to: 1) hide what a user types, but still read the keys. I am working on a program that is involves password protection. I need a way to asks for the pass, but not display it openly just when logging onto any OS. A good example is logging onto linux. It asks for the password, but it does not display what the user enters. 2) code a counter that uses the clock as a seed. For example let say this is the code: cout << "testing"; cout << "1 "; ------------------3 second delay cout << "2 "; ------------------3 second delay cout << "3 "; In other word, is there a way to code some type of delay or counter? Thanks, Kuphryn

Share this post


Link to post
Share on other sites
Xai    1838
you are asking two different questions ... but as for the second one ... the only way to do this in a standard c / c++ single threaded app (as far as i know) ... is to spin in a loop ... peeking at the input buffers using a command that does not wait for input ... and getting the system time ...

here''s the psuedo code:

NORMAL (waiting version)

  
cout << ....
cout << ....
cin >> ...
cout << ...


now inheirantly in a single threaded app each statement only gets executed after the lines above it have completed ... and since cin waits (blocks) until input is received it is impossible to wait for a time to expire in this system.

TIMED VERSION
  
cout << ...
cout << ...
bool done = false;
bool inputIsValid = false;
while(!done)
{
current time = get system time
peek at input
// I don''t know of any standard c commands for this but

// the dos and unix C libraries should include console functions

// that do not block

if(got input)
{
reset last time to current time
if(got ALL input)
{
inputIsValid = true;
done = true;
}
}

if(current time >= expiration time)
done = true;
}
...
now your code is here and you can test inputIsValid to see if the user
types the input or if time expired ...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Thanks.

About function:

getch();

Is it one character per? If yes, it would need to be in a loop structure

Kuphryn

Share this post


Link to post
Share on other sites
kuphryn    210
Okay.
I tried implementing:

getch();

and

getche();

VC++ 6 responded with:

c:\x.cpp(179) : error C2039: ''getch'' : is not a member of ''basic_istream >''

Kuphryn

Share this post


Link to post
Share on other sites
kuphryn    210
Okay thank.

Does anyone know what std:: do I need to include in addition to:

#include
using std::???

I am still getting the error that getch() does not exist even when I include conio.h.

Kuphryn

Share this post


Link to post
Share on other sites
Oluseyi    2103
getch is not a part of the Standard C++ Library, so it is not included in the standard namespace (ie you don''t have to do "using std::anything" to use it).
#include <conio.h>
#include <iostream>
#include <string>
using namespace std; // I know namespace pollution is evil, but I''m lazy
// and haven''t figure out where getline() is
.
int main(int argc, char *argv[])
{
cout << "Enter a string of text and see it displayed. Enter \''Q\'' to quit." << endl;
char c;
int n = 0;
while(((c = getch()) != ''q'') && (c != ''Q''))
{
cout << "String " << ++n;
getline(cin, str);
if(str == "q" || str == "Q")
break;
cout << str;
}
return 0;
}

This works for me.

[ GDNet Start Here | GDNet FAQ | MS RTFM | STL | Google ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
kuphryn    210
Ahh. Thanks.

So there is not way to get getche() to work without namespace std right?

In your code, you have:

while(...c = getche()...)

and then

getline(cin, str)

What role does str play in the algorithm?

Kuphryn

Share this post


Link to post
Share on other sites
Oluseyi    2103
quote:
Original post by kuphryn
So there is not way to get getche() to work without namespace std right?

getch and getche are not part of the std namespace. The work with or without it. I included the std namespace because I''m lazy, and wont look up getline.

quote:
What role does str play in the algorithm?

It is the destination of the string of input entered by the user. It is compared to see if it is "Q" or "q" (if it is, we exit) and displayed if it isn''t.

[ GDNet Start Here | GDNet FAQ | MS RTFM | STL | Google ]
Thanks to Kylotan for the idea!

Share this post


Link to post
Share on other sites
TerranFury    142
Your two questions are seperate and unrelated, right, kuphryn? All you want to do for the first one is to have someone enter a password but not show what is entered? If so, then here''s a simple way to do it:

  

char pw[256]; // Your string

char c; // Stores an individual character

int i = 0; // Stores the array index

for(;;)
{
c = getch(); //Wait for user to input a character

//and set c equal to that character.

if(c == 13) //If the user hit ENTER (13 = ENTER)

{
pw[i] = NULL; //End the string with a NULL character

break; //Exit loop

}
else
{
pw[i] = c; //Add character to string

i++;
}
}

Share this post


Link to post
Share on other sites
kuphryn    210
TerranFury,

Kick ass!!! Very elegant. It works great.

Here is a section of the code where I incorporated your technique with what I am trying to accomplish:


------------------------------------------------------
{
bool veri = false;

string uKeyA, uKeyB, strOpt;

do
{
int tmpCh = 0;
uKsize = 0;

cout << "\nEnter a password (32 chars. max.): ";

while ((tmpCh = getch()) != 13)
uKeyA += tmpCh;

cin.clear();

uKsize = uKeyA.size();

if (uKsize > maxKeySIZE)
{
veri = false;
uKeyA.erase(uKeyA.begin(), uKeyA.end());
}

cout << "\n\nEnter that password one more time: ";

while ((tmpCh = getch()) != 13)
uKeyB += tmpCh;

cin.clear();

if (uKeyA == uKeyB)
{
veri = true;

for (int i = 0; i < uKsize; ++i)
key = uKeyA[i];
}

else
{
veri = false;
uKeyA.erase(uKeyA.begin(), uKeyA.end());
uKeyB.erase(uKeyB.begin(), uKeyB.end());

cout << "\n\nPassword does not match! Try again."
-------------------------------------------------------------


Note: I left some part of it out.

How did you determine integer 13 represents Enter or "\n?" Did you use:

cout << int("\n");

I am also trying to implement something like astrisks for each character like in windows. I am confident I can get that done. The code you post is simple, yet effectively.
----------------

Oluseyi:

Interesting. I think he used NULL to end the string, not to indicate a new line.
----------------

Lastly, here is a simple character array:

char temp[5] = {'a','b','c','d');

It is a rule that the last space has to be NULL? I think it is true if the program sends temp to cout. However, what if temp is used only as a storage variable? Is:

temp[4] = NULL;

required?

Kuphryn


Edited by - kuphryn on December 16, 2001 2:21:06 PM

Share this post


Link to post
Share on other sites
Kylotan    9870
Using ''NULL'' is awkward. It''s not defined as part of C++, so a compiler or header file that provides it could call it whatever it likes. I think MSVC defines it as 0L (zero as a long int) but I''ve seen it defined as (void*)0 before (zero as a pointer to void). Anyway, a string of characters should really be terminated with the zero character : ''\0''. Don''t rely on the compiler to make a conversion for you when you can do it explicitly - saves you on debugging time later.

[ MSVC Fixes | STL | SDL | Game AI | Sockets | C++ Faq Lite | Boost ]

Share this post


Link to post
Share on other sites
kuphryn    210
Message noted.

Deitel and Deitel C++ How to Program highlighted that it is recommend to use "0" or "''\0''" instead of NULL. I will convert from NULL to "0" or "''\0''" where applicable.

Thanks,
Kuphryn

Share this post


Link to post
Share on other sites