如何找到一个字符数组出现在另一个字符数组中的次数?

时间:2019-03-31 07:44:36

标签: c++

我得到了两个数组<label>Approval History</label> </div> <div class="tile-body"> <div class="tableWrapAtX"> <table class="table"> <thead> <tr> <th>Date/Time</th> <th>User</th> <th>Email Address</th> <th>Old Status</th> <th>New Status</th> <th>Comment</th> </tr> </thead> <tbody> <!-- ko foreach: approvalAuditTrail --> <tr> <td><span data-bind="text: updated"></span></td> <td><span data-bind="text: updatedBy"></span></td> <td><span data-bind="text: updatedByEmail"></span></td> <td><span data-bind="text: oldStatus"></span></td> <td><span data-bind="text: approvalStatus"></span></td> <td><span data-bind="text: comments"></span></td> </tr> <!-- /ko --> </tbody> </table> </div> </div> </div> sir。我应该通过使用库sub中的sub函数并删除第一个字母来找出sir被包含在strstr中的次数。例如,<cstring>sir,而omtatatatarshtasub。我可以看到tat首先出现第三个字母,然后从sub中删除了该字母,所以下次我在sir中搜索sub时,我会得到不同的出现。但是我对管理sir(其中x是指针)这一事实感到非常困惑。 x=strstr(sir, sub);是表示nr被发现sub的次数的变量。

首先,我尝试这样做sirfor,但出现错误for(i=x; i<strlen(sir); i++) sir[i]=sir[i+1];。然后,在互联网上查看了一些代码之后,我尝试这样写:invalid comparison between 'char*' to 'int'我对此没有任何错误,但也没有任何结果。

for(char *x; *x!='\0'; *x++) *x=*(x+1);

在我的示例中,#include <iostream> #include <fstream> #include <cstring> using namespace std; ifstream f("info.in"); char sub[20], sir[100]; char* x; int main() { int nr=0, i; f >> sub; f >> sir; cout << sir; x = strstr(sir, sub); while (x) { nr++; for (char* x; *x != '\0'; *x++) *x = *(x + 1); x = strstr(sir, sub); } cout << nr; return 0; } subtatsir,答案应该是3,因为您可以在{{1}中找到omtatatatarshta }三遍。 如我所说,我的代码没有任何结果。

1 个答案:

答案 0 :(得分:1)

可以在C ++中使用C字符串,但不建议这样做。管理C字符串的存储并对其进行处理并不是那么容易且容易出错。

C ++可以很好地替代: std::string 。它提供了类似的功能,但是却负担了应用程序程序员的内存管理负担。

OP老师为何坚持教C字符串处理... Kate Gregory: Stop Teaching C

话虽如此,我不明白为什么OP认为sir中必须删除某些内容。 C字符串的“强度”是–从char*指向那里开始。如果该指针递增n次,则字符串将在n char之后才开始。 (当然,您必须关心0终止符。将指针移到其后可能会导致未定义行为。)

所以,这就是我要做的:

#include <iostream>
#include <cstring>

int main()
{
    const char *const sir = "omtatatatarshta";
    const char *const sub = "tat";
    int nr = 0;
    for (const char *x = sir;; ++nr) {
      x = strstr(x, sub);
      if (!x) break;
      ++x; // inc. x to prevent double matching the same
    }
    std::cout << "nr: " << nr << '\n';
    return 0;
}

输出:

nr: 3

Live Demo on coliru

看看OPs公开的代码,我认为仍然存在对指针如何工作的误解。 (我记得我还需要一段时间来理解它们。)

for (char* x; *x != '\0'; *x++)
        *x = *(x + 1);

这个坏了。

  1. for (char *x; ...引入了仅在x循环中存在的新局部变量for。已经存在的x黯然失色。 (它仍然存在,但在for循环中无法访问。)

  2. for (char *x;声明了x,但未定义它-未初始化。由于x可以具有任意内容,即可以指向任何地方。因此,x的读取内容是未定义的行为(错误)。

  3. for (char* x; *x != '\0'; *x++)*x++“读取” x的内容,然后递增指针x。这不是直接错误,但没有理由读取x的内容。 x++(甚至更好的++x)就足够了。

我将此代码固定为OP打算做的(我相信):

for(; * x!='\ 0'; ++ x)* x = *(x + 1);

此外,我添加了一些打印调试功能,以使内部发生的情况可视化:

#include <iostream>
#include <cstring>

int main()
{
    char sir[] = "omtatatatarshta";
    const char *const sub = "tat";
    int nr = 0;
    std::cout << "sir: '" << sir << "'\n";
    char *x = strstr(sir, sub);
    while (x) {
      ++nr;
      std::cout << "Hit " << nr << '\n';
      for (; *x != '\0'; ++x) *x = *(x + 1);
      std::cout << "sir: '" << sir << "'\n";
      x = strstr(sir, sub);
    }
    std::cout << "nr: " << nr << '\n';
    return 0;
}

输出:

sir: 'omtatatatarshta'
nr: 1
sir: 'omatatatarshta'
nr: 2
sir: 'omaatatarshta'
nr: 3
sir: 'omaaatarshta'
nr: 3

Live Demo on coliru

注意:

请注意第一和第二个示例中我声明sir的方式。

在第一个示例中:const char *const sir = "omtatatatarshta";

sir是指向const的{​​{1}}指针(由于*const)。该声明强制指针和内容均不得更改。指针使用常量字符串const char的地址初始化。

与此相反,"omtatatatarshta"的类型为x。它是指向常量内容的非常量指针。内容没有被触及,因此可以限制为只读。指针已分配(通过const char*)。因此,它可能不是strstr()

在第二个示例中:const

由于char sir[] = "omtatatatarshta";的内容将被更改,因此它必须是一个数组。