我有两个C风格的字符串:
char st[100] = "to be or not to be ";
char sub_s[100] = "be";
我需要用
strstr(st, sub_s)
查找“ be”的开头并将其更改为大写字母。新字符串必须为“”,否则为“;”;我设法做到了没有这样的功能:
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
。可以使用
tolower
标头中的<ctype.h>
函数,而不是从每个字符中减去32(这是有效的,但不是单词中最清楚的东西)。如果您要搜索的子字符串仅由非字母字符(例如
":-)"
)组成,则此代码可能导致无限循环。你明白为什么吗?考虑一下如何解决。关于c - 大写单词的所有副本:为什么此代码在其自身功能中失败?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41769472/