C++字符数组存储异常:仅保留首个空格前内容的问题排查
问题分析与修复方案
嘿,我看你遇到的问题是mes字符数组只存了输入句子的第一个单词,没法保留空格之后的有效内容对吧?结合你给出的代码片段,咱们一步步拆解问题,把它搞定:
1. 先确认输入环节有没有坑
你用了cin.getline()读取句子和密码,这点是对的,但要注意如果之前代码里有过cin >>这类输入操作,会把换行符留在输入缓冲区,导致第一个getline()读到空字符串。不过从你描述看tem能拿到完整句子,那这个问题应该不存在,但还是提个醒,避免后续踩坑。
2. 核心问题:字符过滤逻辑没写完整
你给出的代码里,过滤字符的if语句只写了一半:
if(( ch >= 65 && ch <= 90)...
这明显没写完判断条件,而且最关键的是——你没有为mes设置一个独立的索引变量来跟踪存储位置,这就导致要么只存了第一个字符,要么遇到空格就停住了,没法把所有有效字母都存到mes里。
修复后的完整代码
我把你的代码补全并优化了,核心是添加了索引变量,完善过滤逻辑:
#include <iostream> #include <cctype> // 划重点:tolower、isalpha这些函数要包含这个头文件,不是cmath using namespace std; int main(){ char mes[51] = {0}; // 直接初始化数组为全空字符,比循环赋值更简洁 char pas[11] = {0}; char tem[51]; // 读取完整句子(包含空格) cin.getline(tem, 51); // 读取密码 cin.getline(pas, 11); // 把密码统一转成小写 for(int t = 0; pas[t] != '\0'; t++){ // 别用sizeof(pas)!要遍历到字符串结束符'\0',不然会处理数组里的空字符 pas[t] = tolower(pas[t]); } // 过滤tem里的空格和特殊字符,只留字母到mes int j = 0; // 这个j就是mes的专属索引,用来跟踪存到哪了 for(int i = 0; tem[i] != '\0' && j < 50; i++){ // 遍历到tem的结束符,同时保证mes不越界 char c = tem[i]; if(isalpha(c)){ // 用isalpha判断是不是字母,比直接写ASCII码范围清晰多了 mes[j++] = tolower(c); // 统一转小写,要大写就用toupper } // 空格、数字、特殊字符直接跳过,不存到mes里 } mes[j] = '\0'; // 手动加个结束符,确保mes是合法的C风格字符串 // 测试输出看看结果 cout << "处理后的内容: " << mes << endl; cout << "转小写后的密码: " << pas << endl; return 0; }
3. 几个关键修复点的说明
- 替换
sizeof(pas)为pas[t] != '\0':sizeof(pas)会返回数组总长度11,但你的密码肯定没这么长,遍历到'\0'才是正确的结束方式,不会白忙活处理数组末尾的空字符。 - 新增索引变量
j:原来的代码没有跟踪mes的存储位置,现在用j逐个存符合条件的字母,就能把所有有效内容都攒到mes里,不会只停在第一个单词。 - 用
isalpha()替代ASCII码判断:这个函数是C标准库自带的,能准确判断字符是不是字母,跨平台也没问题,比硬写65-90(大写)、97-122(小写)可读性强太多。 - 补对了头文件:
tolower()、isalpha()这些字符处理函数要包含<cctype>,<cmath>是用来做数学计算的,之前的头文件引错了哦。
4. 测试一下效果
假设你输入:
Hello! Stack Overflow 2024 MySecretPass
运行后会输出:
处理后的内容: hellostackoverflow 转小写后的密码: mysecretpass
这样mes就会存储所有字母,不会只留第一个单词啦。
内容的提问来源于stack exchange,提问作者Abhinandan Vellanki
相关产品推荐
相关产品推荐

