如何修改C++程序以接收用户字符串输入并完成指定字母集校验匹配
C++作业程序改造:单字符输入升级为全字符串校验实现
改造核心逻辑
完全按照作业要求的两层校验流程实现,从根源解决原程序输入多字符就崩溃的问题:
- 替换单char的输入接收逻辑:改用
std::string类型搭配std::getline读取用户输入的完整整行内容,避免原程序直接把多字符输入塞给单char变量导致的缓冲区溢出、流残留引发的异常崩溃 - 第一层校验:全字母合法性检查
逐字符遍历输入的字符串,通过标准库函数判断每个字符是否为英文字母:只要存在任意数字、特殊符号、标点、空格等非字母内容,直接输出指定错误提示,要求用户重新输入 - 第二层校验:目标字母集合匹配(不区分大小写)
把题目指定的reducedAlphabet集合做统一小写存储,逐字符将输入内容转为小写后和集合内元素匹配:只要有任意一个字符不在集合内就输出No,全部匹配成功则输出Ae
关键实现代码
#include <iostream> #include <string> #include <cctype> #include <unordered_set> int main() { // 定义题目要求的目标字母集合,全小写存储适配不区分大小写匹配 const std::unordered_set<char> reducedAlphabet = { 'a', 'e', 'i', 'o', 'u', 'h', 'k', 'l', 'm', 'n', 'p', 'w' }; std::string userInput; while (true) { std::cout << "Please enter your content: "; std::getline(std::cin, userInput); // 第一层:全字母校验 bool hasInvalidSymbol = false; for (char c : userInput) { // 强转unsigned char避免isalpha遇到非ASCII字符时的未定义行为 if (!isalpha(static_cast<unsigned char>(c))) { hasInvalidSymbol = true; break; } } if (hasInvalidSymbol) { std::cout << "Error. Words only. Please try again." << std::endl; continue; } // 第二层:目标字母集合匹配 bool allCharMatched = true; for (char c : userInput) { char lowerChar = tolower(static_cast<unsigned char>(c)); if (reducedAlphabet.find(lowerChar) == reducedAlphabet.end()) { allCharMatched = false; break; } } if (allCharMatched) { std::cout << "Ae" << std::endl; } else { std::cout << "No" << std::endl; } break; // 可根据作业要求调整为循环持续接收输入的逻辑 } return 0; }
常见实现避坑点
- 不要混用输入读取方式:如果原代码保留了
cin >> 单char变量的逻辑,输入缓冲区会残留换行符、多余字符,后续调用getline会读到空内容,需要用std::cin.ignore()清空缓冲区残留再做读取 - 不要手写字母范围判断逻辑:自己写
c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'的判断方式,在非ASCII编码环境下容易出现边界判断错误,直接用标准库的isalpha更稳妥 - 匹配时统一做大小写转换:不要只判断输入字符的原始大小写,统一转成小写后和目标集合比对,避免因大小写不统一出现匹配漏判
- 测试用例全覆盖验证:
- 输入
$5&、-23、abc12、12asd时,因存在非字母字符,触发错误提示 - 输入
Talk时,因字符t不在目标集合,输出No - 输入
mE、nOW时,所有字符都在目标集合内,输出Ae - 输入
yOu时,因字符y不在目标集合内,输出No
内容的提问来源于stack exchange,提问作者drsideburn
相关产品推荐
相关产品推荐

