C++日期解析程序触发访问违例异常,求错误原因分析
分析你的C++程序异常问题
首先,你遇到的0xC0000005: Access violation writing location错误,本质是数组越界访问+无限递归导致的非法内存写入,咱们一步步拆解问题:
核心错误点
1. 数组大小不足且递归无终止条件
你定义的数组int a[2]只有2个元素,但日期需要存储日、月、年三个值。更关键的是,get_date()函数是递归调用,但完全没设置终止逻辑——哪怕已经处理完所有/分割的部分,函数依然会继续递归调用自己,导致j不断增大,最终超出数组a的边界,写入不属于程序的内存区域,触发访问违例。
2. 字符串截取逻辑错误
你的str_date.substr(0, i - 1)写法有误:substr的第二个参数是截取的长度,当找到第一个/在索引i时,前面的日期部分应该从0到i的位置,长度为i,而不是i-1。比如输入12/05/1234,第一个/在索引2,substr(0,2)才能拿到12,用i-1只会拿到1,完全不符合预期。
3. 循环越界访问字符串
for (int i = 0; i <= str_date.length(); i++)这个循环条件有问题:字符串的有效索引是从0到length()-1,当i == str_date.length()时,str_date[i]访问的是字符串末尾的下一个位置,属于非法内存访问,应该改成i < str_date.length()。
修正后的代码
下面是修复了所有问题的版本,添加了递归终止条件,修正了截取逻辑,调整了数组大小:
#include <iostream> #include <string> #include <sstream> using namespace std; // 数组大小改为3,对应日、月、年三个值 int a[3]; int j = 0; string str_date; string str_date_sub; void get_date() { // 先检查是否还有分隔符/ size_t slash_pos = str_date.find('/'); if (slash_pos == string::npos) { // 没有分隔符时,处理最后一部分(年),同时确保不越界 if (j < 3) { stringstream ss(str_date); ss >> a[j]; j++; } return; // 终止递归,这是关键! } // 截取/之前的有效部分 str_date_sub = str_date.substr(0, slash_pos); // 移除已处理的部分(包括/) str_date.erase(0, slash_pos + 1); if (j < 3) { stringstream ss(str_date_sub); ss >> a[j]; j++; } // 递归处理剩余的字符串 get_date(); } int main() { cout << "Please input the date DD/MM/YYYY:\n"; str_date = "12/05/1234"; // 也可以改成cin >> str_date让用户手动输入 get_date(); // 输出验证结果 cout << "Day: " << a[0] << endl; cout << "Month: " << a[1] << endl; cout << "Year: " << a[2] << endl; system("pause"); return 0; }
额外优化建议
- 尽量避免全局变量:可以把数组
a、计数器j作为参数传递给get_date(),或者封装成类,让代码更模块化、更安全。 - 增加输入验证:比如检查输入的日期格式是否符合
DD/MM/YYYY的要求,避免非法输入导致的错误。 - 简化类型转换:使用C++11及以后的
std::stoi函数可以直接将字符串转为int,比stringstream更简洁。
内容的提问来源于stack exchange,提问作者Lệ Trâm
相关产品推荐
相关产品推荐

