2010-04-12 240 views
3

我需要编写一个程序,该程序以两个字符串作为参数,并检查第二个字符串是否是第一个字符串的子字符串。我需要这样做,而不使用任何特殊的库函数。我创建了这个实现,但是我认为只要两个字符串中有一个字母是相同的,就总是返回true。你能帮我在这里吗?我不知道我在做什么错:C - 检查字符串是否是另一个字符串的子字符串

#include <stdio.h> 
#include <string.h> 

int my_strstr(char const *s, char const *sub) { 
    char const *ret = sub; 

    int r = 0; 
    while (ret = strchr(ret, *sub)) { 
     if (strcmp(++ret, sub+1) == 0){ 
      r = 1; 
     } 
     else{ 
      r = 0; 
     }   
    } 
    return r; 
} 

int main(int argc, char **argv){ 

    if (argc != 3) { 
     printf ("Usage: check <string one> <string two>\n"); 
    } 
    int result = my_strstr(argv[1], argv[2]); 

    if(result == 1){ 
     printf("%s is a substring of %s\n", argv[2], argv[1]); 
    } else{ 
     printf("%s is not a substring of %s\n", argv[2], argv[1]); 
    } 
    return 0; 
} 
+4

如果您“需要不使用任何特殊的库函数”,那么您不应该使用strchr和strcmp。其实strcmp是你的问题无论如何。 – stmax 2010-04-12 18:50:19

+0

@stmax:这些只是_ordinary_库函数。没有什么特别的:) – 2010-04-12 18:54:47

+0

@Daniel:如果'strchr()'和'strcmp()'是普通的,那么'strstr()'... – 2010-04-12 21:03:40

回答

1

嘛,你不应该在my_strstr修改ret。并且strcmp不比较子字符串,它比较字符串。您可能想要使用strncmp

0

看起来你是在字符*子寻找字符*子:

int my_strstr(char const *s, char const *sub) { 
char const *ret = sub; 

你不应该被设定RET送?

此外strcmp比较字符串,而不是子字符串,因此strcmp(“abcde”,“abc”)返回false。你可能需要strncmp,它也需要一个指定长度的整数。

3

您的写作方法strstr存在根本性缺陷。让我们来看看你写的:

所有的
char const *ret = sub; 

int r = 0; 
while (ret = strchr(ret, *sub)) { 
    if (strcmp(++ret, sub+1) == 0){ 
     r = 1; 
    } 
    else{ 
     r = 0; 
    }   
} 
return r; 

首先,既然你初始化ret指向sub,你是比较sub对自己,从不看s。但是让我们假设你意味着ret初始化为s ...

ret = strchr(ret, *sub)发现的sub下一个字符的位置内ret,然后前进ret,使其开始在该字符。

然后,执行strcmp(++ret, sub+1),它确定是否从ret的下一个字符开始的字符串等于从sub的下一个字符开始的字符串,然后前进ret开始与下一个字符(不管是否在测试是真的还是假的)。

很明显,这个逻辑没有做你想做的。它实际上要做的是确定子字符串是否等于字符串s,或者在字符串s末尾处找到,并且不包含重复的字母。

这里有你想要的算法的大致轮廓:

  1. 查找ssub的第一个字符的位置。如果找不到,则返回false。
  2. 更新s,使得它开始在该位置
  3. 假设sub长度n,测试,如果s匹配sub(小心,不要运行过去的s的端部)的第一n字符。如果是这样,则返回true。否则,请将s提前一个字符并循环。

请注意,除第一个以外,您不应该搜索sub中的任何字符。这个想法是使用sub的第一个字符来找到潜在的sub的起始位置s,然后检查子字符串sub是否确实存在。如果它不在那里,你希望放弃s到目前为止,然后通过尝试找到下一个潜在的起始位置重新开始。

0

当第一次遇到

ret = strchr(ret, *sub) 

ret == sub。所以,strchr(ret, *sub)正在搜索ret的第一个字符的第一个出现在ret。这将返回ret。因此,ret保持不变。

接下来,

strcmp(++ret, sub+1) == 0 

ret仍然等于sub,所以上面的语句是

而你得到1作为回报。

0

这可能有助于将此任务向下分开。这个任务有两个关键部分:1)找到可能的子字符串匹配的起始点,2)测试该起始点是否确实是匹配的子字符串。因此,将这作为两个功能来实现。

首先,创建一个函数,确定两个字符串是否完全相似。这应该比较容易编码,只需比较第一个字母与第一个字母,第二个与第二个等等。如果发现两个不匹配,则返回false。如果您将其放到其中一个字符串的末尾,请返回true。如果允许使用strncmp,那么这将仅仅是(strncmp(a, b, strlen(b)) == 0)(假设b始终是较短的字符串)。

其次,创建一个循环查找某个字符串的函数。每当它找到该字母时,它就会调用一个函数并将一个指针传递给该字符串中的那个字母。换句话说,如果您调用my_function("This is a sample string", 's'),那么函数应该遍历字符串,找到字母's'的所有四个实例,并使用指向字符串中该字母的指针调用函数。在这种情况下,您要调用的函数是前一段中描述的函数。

使用此细分,只要对子函数的任何调用返回“true”,就会返回“true”,否则,如果将其输入到输入字符串的末尾,您将返回“false”。

0
char const *ret = sub; 

int r = 0; 
while (ret = strchr(ret, *sub)) { 

RET被存储在 子阵列的地址和while语句strchr(ret,*sub)sub存储在ret 这是否会工作或没有地址比较值(这个比较正确与否) 答案请人...

相关问题