[英]Create the strstr function in C from scratch, but with modified strings
总而言之,如果 function 被赋予 arguments char *str1 = "小心街道?"; char *str2 = "street?";,它应该返回 str1 中指向 "street" 的第一个实例的指针,从 s 开始。
我完全被卡住了,感谢任何帮助。 我感觉我的问题出在指针上。 正如你想象的那样,我是一个初学者。
我刚刚将代码编辑为我最近的尝试。 我非常接近,但仍然找不到修改第一个字符串的想法。
Output 图像:
const char *qstr_strstr(const char *str1, const char *str2) {
int j = 0;
char newstr2[256];
while (str2[j]) {
if (str2[j] == '?') {
break;
} else {
newstr2[j] = str2[j];
}
j++;
}
newstr2[j] = '\0';
size_t n = strlen(newstr2);
while(*str1) {
if (!memcmp(str1++, newstr2, n)) {
return (str1 - 1);
}
}
return NULL;
}
您正朝着正确的方向前进,并且您开始考虑正确地通过刺痛,但是您正在使用任何额外的字符串 - 没有必要这样做。
当您分析字符串和子字符串时,您只关心:
str1
。 使您的情况复杂化的是红鲱鱼'?'
特点。 您可以将其用作子字符串结尾的测试,也可以完全忽略它。 您的目标是在str1
"... streets?"
中找到str2
"street"
。 . 您通常会使用ctype.h
中的ispunct()
来识别'?'
作为非单词字符,无论如何都不是字符串的一部分。 在这里,您可以简单地检查'?'
以类似的方式检查'\0'
以标记end-of-string 。
把它放在一起而不使用任何string.h
或ctype.h
函数,你可以这样做:
#include <stdio.h>
const char *qstr_strstr (const char *str1, const char *str2)
{
int i = 0, instr2 = 0, ndx = 0; /* str1 index, in-str2 flag, str2 index */
if (str1 == NULL || str2 == NULL) /* validte both str1 and str2 not NULL */
return NULL;
do { /* loop over each char in str1 */
/* if in str2 and (at end or at '?') */
if (instr2 && (!str2[ndx] || str2[ndx] == '?'))
return &str1[i-ndx]; /* return address in str1 to start of str2 */
/* if char in str1 and str2 equal */
if (str1[i] == str2[ndx]) {
ndx += 1; /* increment str2 index */
instr2 = 1; /* set in-str2 flag true (done each time) */
}
else /* otherwise chars not equal */
ndx = instr2 = 0; /* reset str2 index, set in-str2 flag false */
} while (str1[i++]); /* includes \0, allows match at end of both */
return NULL;
}
int main (void) {
const char *str1 = "Watch of the streets?",
*str2 = "street?",
*ptr = qstr_strstr (str1, str2);
if (ptr) {
size_t i = ptr - str1;
printf ("ptr : %s\nptr addr : %p\n---\n"
"&str1[%zu] : %s\n&str1[%zu] : %p\n",
ptr, (void*)ptr, i, str1 + i, i, (void*)(str1 + i));
}
}
示例使用/输出
输出由qstr_strstr()
重新调整的字符串和 adderss 以及该字符串的地址和位于原始str1
中的地址,您将拥有:
$ ./bin/strstrawk
ptr : streets?
ptr addr : 0x4006c1
---
&str1[13] : streets?
&str1[13] : 0x4006c1
您可以进一步从str1
中的地址复制 substring street
或您需要做的任何其他事情。 如果您还有其他问题,请仔细查看并告诉我。
根据添加的图片编辑
如果你想 output 只是'?'
之前的字符 from the pointer returned by qstr_strstr()
, then you can do that trivially by using the precision modifier with the "%s"
output conversion specifier in your printf
format string and limit the number of characters output to just the number before the '?'
在str2
中。 您的格式转换说明符看起来像"%.*s"
,它需要 2 个 arguments,第一个int
类型是字符数,第二个是字符串。
在上述情况下,arguments 将是:
(int)strcspn (str2, "?"), ptr
其中strcspn()
返回'?'
之前的字符数在str2
(转换为int
)和ptr
从qstr_strstr()
返回。 更改上面的代码,您将拥有:
...
#include <string.h>
...
printf ("ptr : %.*s\nptr addr : %p\n---\n"
"&str1[%zu] : %s\n&str1[%zu] : %p\n",
(int)strcspn (str2, "?"), ptr, (void*)ptr,
i, str1 + i, i, (void*)(str1 + i));
(其余代码不变)
$ ./bin/strstrawk
ptr : street
ptr addr : 0x4006c1
---
&str1[13] : streets?
&str1[13] : 0x4006c1
其中 output 使用ptr
作为字符串并且str2
的长度不是"street"
。
如果您还有其他问题,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.