c++ - 如何找到一个字符数组出现在另一个字符数组中的次数?
问题描述
我得到了 2 个数组sir
和sub
. 我应该通过使用库中的函数并删除第一个字母来找到sub
包含的次数。例如,是和是。我可以看到第一个与第三个字母一起出现 biginning 并且我从中删除了那个字母,所以下次我搜索时我会得到不同的外观。但是我对管理, where是一个指针
这一事实感到非常困惑。是表示可以找到的次数的变量。sir
strstr
<cstring>
sir
omtatatatarshta
sub
tat
sub
sir
sub
sir
x
x=strstr(sir, sub);
nr
sub
sir
首先,我尝试这样做for
:
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;
}
在我的例子sub
中是tat
和sir
是omtatatatarshta
,答案应该是 3,你可以tat
在omtatatatarshta
3 次中找到。正如我所说,我的代码没有得到任何结果。
解决方案
在 C++ 中使用 C 字符串是可能的,但不推荐。管理 C 字符串的存储和处理它们并不是那么容易且容易出错。
C++ 有一个很好的替代品:std::string
. 它提供了类似的功能,但承担了应用程序员的内存管理负担。
为什么 OPs 老师坚持教 C 字符串处理... Kate Gregory:停止教C。
话虽如此,我不明白为什么 OP 认为sir
. C弦的“强度”是——它只是从一个char*
点开始。如果该指针增加 n 次,则字符串将在 nchar
秒后开始。(当然,您必须关心 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
查看 OP 公开的代码,我认为仍然存在误解指针的工作原理。(我记得我也需要一段时间来理解它们。)
for (char* x; *x != '\0'; *x++)
*x = *(x + 1);
这已破了。
for (char *x;
x
... 引入了一个仅存在于for
循环中的新局部变量。已经存在x
的就黯然失色了。(它仍然存在,但在for
循环内部无法访问。)for (char *x;
声明x
但没有定义它——它是未初始化的。x
可能有任何任意内容,即它可以指向任何地方。因此,读取的内容x
是未定义的行为(坏)。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
笔记:
请注意我sir
在第一个和第二个示例中声明的方式不同。
在第一个例子中:const char *const sir = "omtatatatarshta";
sir
是指向 a 的const
指针(由于*const
)const char
。该声明强制指针和内容都不能更改。指针用常量 string 的地址初始化"omtatatatarshta"
。
与此相反,x
has 类型const char*
。它是指向常量内容的非常量指针。内容没有被触及,因此它可以被限制为只读。指针被分配(由strstr()
)。因此它可能不是const
。
在第二个例子中:char sir[] = "omtatatatarshta";
.
由于sir
要更改的内容,它必须是一个数组。
推荐阅读
- c# - 如何使用滑动输入选择多个按钮
- php - PHP Live Server/Live Server Extension for Google Chrome 使用 VS 代码编辑器
- javascript - 如何使用 setTimeout 函数 JS 制作 ping 命令
- python - 如何在 send_keys 中转义“/”?
- python - 为龙与地下城进行深入的“测验”
- json - mongodb map减少值未定义
- python - 如何在 3D 散点图中切换轴的方向?
- java - 程序在执行时无法正确写入/读取文件
- image - 使用 Sass 基于视口动态显示静态图像
- scala - 如何在 sbt 子项目中引用父项目的设置?