资本化一个单词的所有副本:为什么此代码在它自己的函数中失败?
我有两个C风格字符串:资本化一个单词的所有副本:为什么此代码在它自己的函数中失败?
char st[100] = "to be or not to be ";
char sub_s[100] = "be";
我需要找到开头的“是”与strstr(st, sub_s)
并将其更改为大写字母。新的字符串需要''是或不是'“;
我管理与做出来的功能,像这样:
void main()
{
char st[100] = "to be or not to be ";
char sub_s[100] = "be";
char* p;
int i;
while (p = strstr(st, sub_s))
{
for (i = 0; i < strlen(sub_s); i++)
{
p[i] -= 32;
}
}
printf("%s\n", st);
}
但是,当我把这个代码到它自己的功能不工作了:
void main()
{
char st[100] = "to be or not to be ";
char sub_s[100] = "be";
replaceSubstring(st, sub_s);
}
void replaceSubstring(char* str, char* substr)
{
int* p;
int i;
while (p = strstr(str, substr))
{
for (i = 0; i < strlen(substr); i++)
{
p[i] -= 32;
}
}
printf("%s\n", st);
}
这是怎么回事在这?
在您编写的函数中,您已将p
的类型设置为int*
而不是char *
。这意味着,当你写
p[i] -= 32;
编译器将假定在由p
每个元素指出为int
,因此采取尺寸sizeof(int)
的在存储器中的步骤,而不是尺寸1的存储器中的步骤。换句话说,代码被解释为
Start at the location pointed at by p.
Jump forward i * sizeof(int) bytes.
Read an integer value from that location.
Subtract 32 from it.
Write it back
而非
Start at the location pointed at by p.
Find the character i steps down from there.
Subtract 32 from that character.
为了解决这个问题,更改的p
类型为char*
,不int*
。
这是一种错误,如果您将编译器警告级别设置为最大值,可能很容易检测到这种错误。当你学习编码时,我强烈建议你这样做,然后询问你在不了解它们时得到的警告。
其他一些杂散注意事项:
- 的
main
返回类型应该是int
,不void
。 - 不是从每个字符中减去32个字符,但这不是这个字中最清晰的东西,可以考虑使用
<ctype.h>
标头中的tolower
函数。 - 如果您要搜索的子字符串仅包含非字母字符(例如,
":-)"
),则此代码可能导致无限循环。你明白为什么?想想你如何解决它。
谢谢! ,我现在明白了/但是我们没有学习过的东西。为什么它会是无限循环?我的while循环说:尝试找到str中的子字符串,如果是的话做一些事情。如果不是,他会继续直到字符'/ 0',否? – marvelX
如果你使用tolower而不是减去32,如果你尝试用':-)'的字符串':-) :-)'来覆盖':-)'的所有副本,会发生什么?玩这个,看看你找到了什么。如果您不确定发生了什么,请发表另一个问题! – templatetypedef
@chux Hahahaha,哎呀,最近做了太多的C++。 :-) – templatetypedef
代码和输出不应该在图像中,你需要把代码和输出作为格式正确的文本在你的问题。 –
您在函数示例中使用了'int * p'。为什么? – 16tons
请不要张贴图像,除非他们绝对必要 –