【问题标题】:Problem : "String subscript out of range" C++问题:“字符串下标超出范围”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 ! ";
    }
}

【问题讨论】:

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

标签: c++ string


【解决方案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

【讨论】:

  • 我真的很感激!非常感谢
猜你喜欢
  • 2013-04-22
  • 2012-04-27
  • 2015-03-31
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多