如何在C++中创建无指定大小动态数组并实现灵活密码输入
问题解决方案
一、修改密码输入逻辑(支持任意长度,回车停止)
原代码限制了8位密码长度,且会把回车键当作普通字符处理。我们可以用std::string动态存储输入内容,调整输入循环逻辑,直到用户按下回车才停止输入,同时优化退格键的处理(避免输入错误无法修正)。
核心修改点:
- 替换固定长度字符数组:把全局的
char pass[8], inPass[8];改成std::string pass, inPass;,利用string的动态扩容特性存储任意长度密码。 - 重写输入循环:循环读取按键,遇到回车停止,遇到退格则删除已输入字符并清除屏幕上的
*。 - 修正密码验证逻辑:避免原代码中
while (!f.eof())的重复读取问题,直接读取文件中完整密码进行比对。
修改后的完整代码:
#include <iostream> #include <fstream> #include <string> #include <conio.h> // 用于_getch()和_putch() bool CheckCredentials(std::string); std::string pass, inPass; int main() { bool done = false; while (!done) { std::cout << "1. Register a password" << std::endl; std::cout << "2. Login your password" << std::endl; std::cout << "3. Exit" << std::endl; int menuChoice; std::cin >> menuChoice; std::cin.ignore(); // 清除输入缓冲区的换行符,避免影响后续_getch() if (menuChoice == 1) { std::ifstream ifile("password.txt"); if (ifile.is_open()) { std::cout << "Password already registered!\n\n"; ifile.close(); } else { std::cout << "Enter password (press Enter to finish): "; char ch; while ((ch = _getch()) != '\r') { // 检测回车键(Windows下为'\r') if (ch == '\b') { // 处理退格键 if (!pass.empty()) { pass.pop_back(); std::cout << "\b \b"; // 清除屏幕上的*号 } } else { pass.push_back(ch); _putch('*'); // 显示*号隐藏真实密码 } } std::cout << "\n\n"; std::ofstream l("password.txt", std::ios::out); if (!l.is_open()) { std::cout << "could not open file \n"; } else { l << pass; // 直接写入完整密码字符串 l.close(); } pass.clear(); // 清空密码变量,避免残留 } } else if (menuChoice == 2) { std::cout << "Password: "; char ch; while ((ch = _getch()) != '\r') { if (ch == '\b') { if (!inPass.empty()) { inPass.pop_back(); std::cout << "\b \b"; } } else { inPass.push_back(ch); _putch('*'); } } std::cout << std::endl; if (CheckCredentials(inPass)) { std::cout << "\nLogin successful!" << "\n\n"; } else { std::cout << "\nLogin failed!\n\n"; } inPass.clear(); // 清空输入的密码,避免下次登录残留 } else if (menuChoice == 3) { done = true; break; } else { std::cout << "Invalid choice! Please try again.\n\n"; } } return 0; } bool CheckCredentials(std::string inPass) { std::string storedPass; bool status = false; std::ifstream f("password.txt"); if (!f.is_open()) { std::cout << "Unable to open file!\n"; } else { std::getline(f, storedPass); // 读取文件中完整的注册密码 status = (inPass == storedPass); // 直接比较输入密码和存储密码 } f.close(); return status; }
二、C++中无需指定大小的动态数组实现方法
C++提供了多种无需提前指定大小的动态数组方案,常用的有以下三种:
- std::string:专门用于存储字符序列的动态容器,自动管理内存,支持动态扩容、插入、删除等操作,适合存储密码这类字符数据,就是上面代码中用到的方式。
- std::vector
:通用型动态数组容器,可存储任意类型数据(如 vector<int>、vector<char>),会根据元素数量自动调整内存大小,提供push_back()、pop_back()等便捷操作,是C++最常用的动态数组方案。 - 手动new[]分配:用
char* arr = new char[initialSize];手动分配内存,若需扩容需重新分配并拷贝数据,最后必须用delete[] arr;释放内存。这种方式易引发内存泄漏,代码复杂度高,非必要不推荐。
std::vector示例:
#include <vector> #include <iostream> int main() { std::vector<char> dynamicArr; char ch; std::cout << "Enter characters (press Enter to stop): "; while ((ch = getchar()) != '\n') { dynamicArr.push_back(ch); } // 输出数组内容 std::cout << "You entered: "; for (char c : dynamicArr) { std::cout << c; } std::cout << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者Yusuf Yılmaz
相关产品推荐
相关产品推荐

