问题:“字符串下标超出范围”C++

Posted

技术标签:

【中文标题】问题:“字符串下标超出范围”C++【英文标题】:Problem : "String subscript out of range" C++ 【发布时间】:2021-08-23 17:23:10 【问题描述】:

请帮我调试这段代码。它给了我一个错误“字符串下标超出范围”

我不知道为什么。程序需要在字符串中查找子字符串的个数。

代码如下:

#include <iostream>
#include <string>
using namespace std;
int main() 
    string s1;
    string s2;
    int count = 0;
    int m = 0;
    int n = 0;
    cout << "String : ";
    getline(cin, s1);
    cout << "Substring : ";
    getline(cin, s2);
    int len = s2.length();
    while (s1[n] != ' ') 
        if (s1[n] == s2[m]) 
            while (s1[n] == s2[m] && s1[n] != '\0') 
                n++;
                m++;
            
            if (m == len && (s1[n] == ' ' || s1[n] == '\0' )) 
                count++;
            
        
        else 
            while (s1[n] != ' ') 
                n++;
                if (s1[n] != '\0') 
                    break;
                
            
        
        n++;
        m = 0;
    
    if (count == 0) 
        cout << "String contains no subtring ! ";
    
    else if (count > 0) 
        cout << "String contains " << count << " substring ! ";
    

【问题讨论】:

How to debug small programs 您是否在调试器中运行过程序?它应该准确地告诉您发生这种情况的位置以及当时的程序状态。 "String subscript out of range" 的哪一部分您不清楚?这意味着你的一根琴弦越界了。您应该通过调试器运行您的代码,并准确查看您的索引在哪里不是您所期望的。但是,我已经可以告诉你while (s1[n] != ' ') ... n++; 是通过std::string 建立索引的错误方法。而且我可以在您的循环中看到很多可以越界访问的地方。你知道std::string 有一个find() 搜索子字符串的方法吗? 看起来您允许n 的长度超过字符串的长度。 如果你使用at而不是[]来索引,你会得到一些超出范围的保护。将 s1[n] 替换为 s1.at(n) 并同样替换为其余代码。它仍然会出错,但现在会出现异常。 【参考方案1】:

您没有正确循环字符串,因此您最终会超出范围,从而导致未定义的行为。您不应该使用字符值来知道何时到达字符串的末尾,而是使用索引。

试试这样的:

#include <iostream>
#include <string>
using namespace std;

int main() 
    string s1, s2;

    do 
        cout << "String : ";
        getline(cin, s1);
    
    while (s1.empty());

    do 
        cout << "Substring : ";
        getline(cin, s2);
    
    while (s2.empty());

    string::size_type s1_size = s1.size(),
                      s2_size = s2.size(),
                      m = 0,
                      n = 0,
                      k;
    int count = 0;

    while (n < s1_size) 
        if (s1[n] == s2[m]) 
            k = n;
            do 
                ++n;
                ++m;
            
            while (n < s1_size && m < s2_size && s1[n] == s2[m]);
            if (m == s2_size) 
                ++count;
            
            else 
                n = k + 1;
            
            m = 0;
        
        else 
            ++n;
        
    

    if (count == 0) 
        cout << "String contains no substring!";
    
    else 
        cout << "String contains substring " << count << " time(s)!";
    

Online Demo

如果你改用std::string::find(),这可以大大简化,例如:

#include <iostream>
#include <string>
using namespace std;

int main() 
    string s1, s2;

    cout << "String : ";
    getline(cin, s1);
    cout << "Substring : ";
    getline(cin, s2);

    string::size_type pos = 0;
    int count = 0;

    while ((pos = s1.find(s2, pos)) != string::npos) 
        ++count;
        pos += s2.size();
    

    if (count == 0) 
        cout << "String contains no substring!";
    
    else 
        cout << "String contains substring " << count << " time(s)!";
    

Online Demo

【讨论】:

我真的很感激!非常感谢

以上是关于问题:“字符串下标超出范围”C++的主要内容,如果未能解决你的问题,请参考以下文章

C++检查和修改字符串/字符串下标超出范围

我收到“字符串下标超出范围错误”。我不知道为啥

从字符数组更改为字符串时出现“字符串下标超出范围”错误?

调试断言失败,字符串下标超出范围

字符串下标超出范围,使用散列 ADT

访问 std::string 中的空终止字符(字符串下标超出范围)