30/09/2018, 17:58

[Hỏi] Chương trình mật khẩu đơn giản trong C++

em có 1 chương trình nhỏ sau
Viết 1 chương trình nhập mật khẩu, mk không quá 10 kí tự, kiểm tra tính đúng sai(mk gốc được đặt sẵn)
khi nhập in ra các kí tự * để bảo vệ mk người dùng. Chương trình cho phép nhập tối đa 3 lần.

#include <iostream>
#include <string>
#include <conio.h>
using namespace std;
main()
{
	string pwRoot = "12345678";
	string pwUser;
	cout<<"Nhap Password"<<endl;
	int limit =0;
	while (limit <3)
	{
		int i=0;
		char a=getch();
		while ( a!= 13 && a!= 10  && i<10)
		{
			if (a != 8 )
			{
				cout<<'*';
				pwUser[i++]=a;
				a=getch();
			}
			// problem here !!!
		}
		pwUser[i] = '';
		if (  pwRoot == pwUser  ) 
		{
			cout<<endl;
			cout<<"mk ban nhap la"<<pwUser<<endl;
			cout<<"Mat khau dung"<<endl;
			break;
		}
		else 
		{
			cout<<endl<<"Mat khau sai, Nhap lai"<<endl;
			limit++;	
		}
	}	
	if (limit > 2 ) cout <<"Nhap sai 3 lan, vui long thu lai sau"<<endl;
	system("pause");
	return 0;
}

em đang thắc mắc làm thế nào để loại bỏ kí tự backspace nhưng nó vẫn hoạt động
nếu e để vòng

while ( a!= 13 && a!= 10  && i<10 && a!= 8); 

thì nó nhận được kí tự backspace nó sẽ thoát luôn, không để điều kiện a!=8 thì nó lại nhận cả kí tự backspace vào chuỗi mật khẩu pwUser
e thêm điều kiện

if (a != 8 )
{
    cout<<'*';
    pwUser[i++]=a;
    a=getch();
}

thì vấn đề nảy sinh thêm là, khi nhận kí tự backspace nó sẽ k ghi vào xâu pwUser , nhưng lại k biết thực hiện gì, nếu e dùng continue thì sẽ bị nhận thiếu số kí tự bằng số lần bấm backspace,
mà ví dụ khi gõ sai muốn xóa gõ lại, bấm backspace nên việc loại bỏ space nhưng vẫn để nó hoạt động là cần thiết, e đã tính đến trường hợp xóa đi 1 phần tử trong chuỗi pwUser khi mà ng dùng nhập 1 kí tự backspace, tương tự xóa n kí tự trong mảng đó khi nhập n kí tự space cho đến khi hết , nhưng kí tự khi xóa xong, trong mảng sẽ giảm số phẩn tử, nhưng trên màn hình, dấu * in ra lại k thể mất. vây phải làm sao ạ. Xincamon

viết 20:09 ngày 30/09/2018

trước tiên là thêm kí tự vào chuỗi pwUser ko phải viết như vậy pwUser[i++]=a; mà phải viết là pwUser += a;

còn nếu a == '\b' thì để “xóa” 1 ký tự đã hiển thị trên màn hình thì chỉ cần output “\b \b” là được. \b là lùi con nháy về trái 1 ký tự, dấu cách để “xóa” ký tự đó rồi \b nữa để lùi lại vị trí sau khi xóa.

nên ghi là a == '\b' thay vì a == 8 vì số 8 là ký tự gì? Tương tự 13 và 10 là ký tự gì? Nên ghi là '\r''\n'.

để giới hạn ko nhập quá 10 ký tự thì kiểm tra if (pwUser.length() < 10) thì mới thêm a vào pwUser, còn ko thì đừng làm gì cả.

abcxyz viết 20:14 ngày 30/09/2018

trước tiên là thêm kí tự vào chuỗi pwUser ko phải viết như vậy pwUser[i++]=a; mà phải viết là pwUser += a;

mình có nhầm giữa string.h trong c và string trong c++

còn nếu a == ‘\b’ thì để “xóa” 1 ký tự đã hiển thị trên màn hình thì chỉ cần output “\b \b” là được. \b là lùi con nháy về trái 1 ký tự, dấu cách để “xóa” ký tự đó rồi \b nữa để lùi lại vị trí sau khi xóa.

nên ghi là a == ‘\b’ thay vì a == 8 vì số 8 là ký tự gì? Tương tự 13 và 10 là ký tự gì? Nên ghi là ‘\r’ và ‘\n’.

mình dùng 8 , 13, 10 được mà, 1 kí tự thì có nhiều các biểu diễn, biểu diễn hệ 8, hệ 10. hệ 16, hoặc với những kí tự hiển thị được thì viết trong dấu ’ ', 8 là mã hệ 10 của kí tự backspace, còn 13 và 10 là kí tự xuống dòng và quay về đầu dòng, chính là dấu enter đó, dấu enter là sự kết hợp của kí tự xuống dòng và quay về đầu dòng mà,

viết 20:07 ngày 30/09/2018

ta viết thử

bỏ qua vụ mũi tên trái phải, nếu có mũi tên trái phải nữa thì phức tạp hơn nhiều.

#include <iostream>
#include <conio.h>
#include <string>
#include <cctype>

std::string passwordInput(unsigned maxLength)
{
    std::string pw;
    for (char c; (c = getch()); )
    {
        if (c == '\n' || c == '\r') { //phím enter
            std::cout << "\n";
            break;
        } else if (c == '\b') { //phím backspace
            std::cout << "\b \b";
            if (!pw.empty()) pw.erase(pw.size()-1);
        } else if (c == -32) { //phím mũi tên
            _getch(); //bỏ qua kí tự tiếp theo (hướng mũi tên)
        } else if (isprint(c) && pw.size() < maxLength) { //isprint tức là chỉ nhận những ký tự in ra được (có tính khoảng trắng)
            std::cout << '*';
            pw += c;
        }
    }
    return pw;
}

int main()
{
    std::cout << "Password: ";
    std::string password = passwordInput(10);
    std::cout << "Your password is: " << password << "\n";
}
abcxyz viết 20:03 ngày 30/09/2018

tại sao bạn không sử dụng using namespace std; để tối ưu số lần gõ std trước cout và cin, endl
2 cái này đều cho biết những hàm kia thuộc chuẩn std mà, sao cứ phải gõ lại std mỗi khi sử dụng những hàm đó, có lý do gì nên dùng thế hả bạn?

std::cout << "Password: ";
std::string password = passwordInput(10);
std::cout

viết 20:12 ngày 30/09/2018

để tránh gọi trùng tên thôi. namespace giống như có thêm cái họ, gọi std::cout là gọi cả tên họ cho nó cụ thể. Tập viết quen rồi thì thấy cũng chả mất thời gian bao nhiều đâu.

nhatlonggunz viết 20:01 ngày 30/09/2018

A post was merged into an existing topic: Topic này chứa các post được cho là Off-topic

Mai Anh Dũng viết 20:03 ngày 30/09/2018

Đạt nghĩ topic tới đây là ổn rồi, auto close sau 12h nhé

Mai Anh Dũng viết 20:02 ngày 30/09/2018

This topic was automatically closed after 12 hours. New replies are no longer allowed.

Bài liên quan
0