求问C语言中段错误原因?

小白想请教一下,
这道题目是PAT甲级1071 Speech Patterns PTA1071
不知道为什么自己最后一个测试点报段错误。

#include<bits/stdc++.h>
//#define inf 0x3f3f3f
using namespace std;
string s1;
map<string,int> mp;
bool judge(char ch){
    if(ch>='0'&&ch<='9') return true;
    if(ch>='a'&&ch<='z') return true;
    if(ch>='A'&&ch<='Z') return true;
    return false;
}
int main(){
    getline(cin,s1);
    int len=s1.length();
    int sta,cur=0;
    bool flag=false;
    string s2=s1;
    while(cur<=len){
        while(!judge(s1[cur])){
            cur++;
        }
        if(cur>len) break;
        //now cur point to char
        sta=cur;
        while(judge(s1[cur])){
            cur++;
            if(cur>len){break;}
        }
        if(cur>len) break;
        s2=s1.substr(sta,cur-sta);
        for(int i=0;i<s2.length();i++){
            if(s2[i]>='A'&&s2[i]<='Z'){
                s2[i]=s2[i]-'A'+'a';
            }
        }
        if(mp.find(s2)==mp.end()){
            mp[s2]=1;
        }
        else{
            mp[s2]++;
        }
    }
    map<string,int>::iterator ite;
    string k=s1;
    int maxx=-1;
    for(ite=mp.begin();ite!=mp.end();++ite){
        if(ite->second>maxx){
            maxx=ite->second;
            k=ite->first;
        }
       // cout<<ite->first<<" "<<ite->second<<endl;;
    }
    cout<<k<<" "<<maxx<<endl;
    return 0;
}

有两处字符串访问越界,需要修改一下,在代码中已添加注释,测试过所有样例。

#include <iostream>  
#include <cstdio>
#include <string>
#include <stack>
#include <cstring>
#include <vector>
#include <queue>
#include <set>  
#include <map>  
#include <sstream>
#include <cmath>  
#include <algorithm> 
using namespace std;
string s1;
map<string, int> mp;
bool judge(char ch) {
    if (ch >= '0'&&ch <= '9') return true;
    if (ch >= 'a'&&ch <= 'z') return true;
    if (ch >= 'A'&&ch <= 'Z') return true;
    return false;
}
int main() {
    getline(cin, s1);
    int len = s1.length();
    int sta, cur = 0;
    bool flag = false;
    string s2 = s1;
    while (cur < len) {  //  此处需要修改,当cur==len时,字符串访问越界
        while (!judge(s1[cur])) {
            cur++;
        }
        if (cur > len) break;
        //now cur point to char
        sta = cur;
        while (judge(s1[cur])) {
            cur++;
            if (cur >= len) { break; }  // 同理此处需要修改,当cur==len时,字符串访问越界,需要提前break
        }
        //if (cur > len) break;
        s2 = s1.substr(sta, cur - sta);
        for (int i = 0; i < s2.length(); i++) {
            if (s2[i] >= 'A'&&s2[i] <= 'Z') {
                s2[i] = s2[i] - 'A' + 'a';
            }
        }
        if (mp.find(s2) == mp.end()) {
            mp[s2] = 1;
        }
        else {
            mp[s2]++;
        }
    }
    map<string, int>::iterator ite;
    string k = s1;
    int maxx = -1;
    for (ite = mp.begin(); ite != mp.end(); ++ite) {
        if (ite->second > maxx) {
            maxx = ite->second;
            k = ite->first;
        }
        // cout<<ite->first<<" "<<ite->second<<endl;;
    }
    cout << k << " " << maxx << endl;
    return 0;
}

看了题主的代码,觉得提取子字符串的时候有点绕,附上我自己写的代码,作为交流学习。

#include <iostream>  
#include <cstdio>
#include <string>
#include <stack>
#include <cstring>
#include <vector>
#include <queue>
#include <set>  
#include <map>  
#include <sstream>
#include <cmath>  
#include <algorithm> 
using namespace std;  

map<string, int> t;

int main() 
{
    string str;
    getline(cin, str);
    transform(str.begin(), str.end(), str.begin(), ::tolower);
    int start = 0, end = 0;
    for (int i = 0; i < str.length(); i++)
    {
        if ((str[i] <= '9'&&str[i] >= '0') || (str[i] <= 'z' && str[i] >= 'a') || (str[i] <= 'Z' && str[i] >= 'A'))
        {
            end++;
        }
        else
        {
            if (end > start)
            {
                string temp = str.substr(start, end - start);
                t[temp]++;
            }
            start = i + 1;
            end = start;
        }
    }
    if (end > start)
    {
        string temp = str.substr(start, end - start);
        t[temp]++;
    }
    int minl = -1;
    string index = "";
    map<string, int>::iterator ptr;
    for (ptr = t.begin(); ptr != t.end(); ptr++)
    {
        if (ptr->second > minl)
        {
            minl = ptr->second;
            index = ptr->first;
        }
    }
    cout << index << " " << minl;
    return 0;
}