免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 11435 | 回复: 16

求高手指教,在字符串中查找子串,并返回其位置 [复制链接]

论坛徽章:
0
发表于 2011-08-26 20:22 |显示全部楼层
本帖最后由 snowboy9859 于 2011-08-27 14:23 编辑

如题,该代码不能返回正确的位置也不能返回正确的子串,请高手们帮我分析一下代码错在哪里,多谢。
经过自己不懈的努力已经解决,谢谢大家的关注,我已经贴出解决方案了
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. char *substr_search(const char *s1, const char *s2, int *postion)
  4. {
  5.         int n = 0;
  6.         int pos = 0;
  7.         if(*s2)
  8.         {
  9.                 while(*s1)//if(*s1),在此处犯下了个低级错误,现在已经解决。
  10.                 {
  11.                                 for(n=0; *(s1+n)==*(s2+n); n++)
  12.                                 {
  13.                                         if(!*(s2+n+1))
  14.                                         {       
  15.                                                 *postion = pos;
  16.                                                 return (char *)s1;
  17.                                         }
  18.                                 }
  19.                                
  20.                                 pos++;
  21.                                 s1++;
  22.                 }
  23.                
  24.                 *postion = pos;
  25.                 return NULL;
  26.         }
  27.         else
  28.         {
  29.                 *postion = pos;
  30.                 return (char *)s1;
  31.         }
  32.                
  33.                 return NULL;
  34. }

  35. int main(void)
  36. {
  37.         char str1[100] = "abcdefghijkl";
  38.         char str2[100] = "fgh";
  39.         char *tmp = NULL;
  40.         int pos;
  41.        
  42.         tmp = substr_search(str1, str2, &pos);
  43.        
  44.         printf("the sub string postion:%d\n", pos);       
  45.         printf("return string:");
  46.         printf("%s",tmp);
  47.         printf("\n");
  48.        
  49.         return 0;
  50. }
复制代码
运行结果如下:
1.jpg
改正后能够达到预期的效果,效果图如下:
2.jpg

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2011-08-26 23:50 |显示全部楼层
回复 1# snowboy9859


    我自己寫了個:


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. char *my_strstr(const char *haystack, const char *needle);
  5. void report_bug(const char *a, const char *b, const char *c);
  6. void report_status(const char *a, const char *b, const char *c);

  7. #define ARRAYLEN(a) (sizeof(a)/sizeof(a[0]))

  8. int
  9. main(void)
  10. {
  11.         int found_bug, verbose;

  12.         /* FIXME: add option to set verbose */
  13.         verbose = 1;

  14.         struct {
  15.                 char *a, *b;
  16.         } testcase[] = {
  17.                 { NULL, NULL  },
  18.                 { NULL, "abc" },
  19.                 { "abc", NULL },
  20.                 { "abc", "ab" },
  21.                 { "abc", "bc" },
  22.                 { "ab", "abc" },
  23.                 { "aaabc", "aabc" }
  24.         };

  25.         found_bug = EXIT_SUCCESS;
  26.         for (unsigned int i = 0; i < ARRAYLEN(testcase); i++) {
  27.                 char *a, *b, *c1, *c2;

  28.                 a = testcase[i].a;
  29.                 b = testcase[i].b;
  30.                 c1 = my_strstr(a, b);

  31.                 /* strstr doesn't allow empty a or b. */
  32.                 if (a == NULL || b == NULL) {
  33.                         if (c1 != NULL) {
  34.                                 report_bug(a, b, c1);
  35.                                 found_bug = EXIT_FAILURE;
  36.                         }
  37.                         if (verbose)
  38.                                 report_status(a, b, c1);
  39.                         continue;
  40.                 }

  41.                 c2 = strstr(a, b);
  42.                 if (c2 == NULL) {
  43.                         if (c1 != c2) {
  44.                                 report_bug(a, b, c1);
  45.                                 found_bug = EXIT_FAILURE;
  46.                         }
  47.                 }
  48.                 else {
  49.                         if (strcmp(c1, c2) != 0) {
  50.                                 report_bug(a, b, c1);
  51.                                 found_bug = EXIT_FAILURE;
  52.                         }
  53.                 }
  54.                 if (verbose)
  55.                         report_status(a, b, c1);
  56.         }
  57.         exit(found_bug);
  58. }

  59. char *
  60. my_strstr(const char *haystack, const char *needle)
  61. {
  62.         int i, j, pos;

  63.         if (haystack == NULL || needle == NULL) {
  64.                 return NULL;
  65.         }

  66.         pos = -1;
  67.         while (1) {
  68.                 for (i = pos + 1; haystack[i] != needle[0]; i++)
  69.                         ;

  70.                 pos = i++;
  71.                 for (j = 1; haystack[i] && needle[j] && haystack[i] == needle[j]; i++, j++)
  72.                         ;

  73.                 if (needle[j] == '\0')
  74.                         return (char *)(haystack + pos);
  75.                 else {
  76.                         /* HAYSTACK is exhausted. */
  77.                         if (haystack[i] == '\0')
  78.                                 return NULL;
  79.                 }
  80.         }
  81. }

  82. void
  83. report(const char *s, const char *a, const char *b, const char *c)
  84. {
  85.         a = a ? a : "NULL";
  86.         b = b ? b : "NULL";
  87.         c = c ? c : "NULL";
  88.         fprintf(stderr, "%s: a = %s, b = %s, c = %s\n", s, a, b, c);
  89. }
  90. void
  91. report_bug(const char *a, const char *b, const char*c)
  92. {
  93.         report("BUG", a, b, c);
  94. }

  95. void
  96. report_status(const char *a, const char *b, const char*c)
  97. {
  98.         report("SUCCESS", a, b, c);
  99. }
复制代码
測試:

  1. lee@debian:~/code-fragment/2011/08$ gcc -std=gnu99 strstr.c -o /tmp/ss   
  2. lee@debian:~/code-fragment/2011/08$ /tmp/ss
  3. SUCCESS: a = NULL, b = NULL, c = NULL
  4. SUCCESS: a = NULL, b = abc, c = NULL
  5. SUCCESS: a = abc, b = NULL, c = NULL
  6. SUCCESS: a = abc, b = ab, c = abc
  7. SUCCESS: a = abc, b = bc, c = bc
  8. SUCCESS: a = ab, b = abc, c = NULL
  9. SUCCESS: a = aaabc, b = aabc, c = aabc
复制代码

论坛徽章:
0
发表于 2011-08-27 09:20 |显示全部楼层
回复 2# MMMIX


    我要的结果是返回子串所在的位置和字符串,您的代码可以返回字符串

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2011-08-27 10:03 |显示全部楼层
回复  MMMIX


    我要的结果是返回子串所在的位置和字符串,您的代码可以返回字符串
snowboy9859 发表于 2011-08-27 09:20



    需要位置返回一下不就結了?又不是沒有找到位置。

论坛徽章:
0
发表于 2011-08-27 13:39 |显示全部楼层
本帖最后由 davidfoxhu 于 2011-08-27 13:46 编辑

先给你linux内核中的代码:
size_t strnlen(const char *s, size_t count)
{
        const char *sc;

        for (sc = s; count-- && *sc != '\0'; ++sc)
                /* nothing */;
        return sc - s;
}

int memcmp(const void *cs, const void *ct, size_t count)
{
        const unsigned char *su1, *su2;
        int res = 0;

        for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
                if ((res = *su1 - *su2) != 0)
                        break;
        return res;
}

char *strstr(const char *s1, const char *s2)
{
        size_t l1, l2;

        l2 = strlen(s2);
        if (!l2)
                return (char *)s1;
        l1 = strlen(s1);
        while (l1 >= l2) {
                l1--;
                if (!memcmp(s1, s2, l2))
                        return (char *)s1;
                s1++;
        }
        return NULL;
}

需要int的位置值,可以先判断一下返回值,如果不为NULL,则减掉首指针就是位置的int值了。
你的那个代码,粗看了一下,按你的思路,藐视需要两个循环(如有错望见谅):
      for(s1=>0--len1-1)
           for(s2=>0---len2-1)
才能比较,一个循环不行。

论坛徽章:
0
发表于 2011-08-27 14:15 |显示全部楼层
回复 5# davidfoxhu


    非常感谢你的热心,我已经将问题搞定,证明我的思路是可以的,你可以看看我的解决方案

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2011-08-27 14:28 |显示全部楼层
回复  davidfoxhu


    非常感谢你的热心,我已经将问题搞定,证明我的思路是可以的,你可以看看我的解 ...
snowboy9859 发表于 2011-08-27 14:15



    三種實現用的是同一種算法。

论坛徽章:
0
发表于 2011-08-27 14:28 |显示全部楼层
回复 4# MMMIX


    for (i = pos + 1; haystack != needle[0]; i++)

                        ;

代码中的这段,如果条件haystack != needle[0]; 永远不满足即所查的字符串根本不在源字符串中,会不会造成死循环?会不会内存泄露?请指教

论坛徽章:
0
发表于 2011-08-27 14:31 |显示全部楼层
回复 7# MMMIX


    哪三种实现?我没看明白,请多指教!

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
发表于 2011-08-27 14:41 |显示全部楼层
回复  MMMIX


    for (i = pos + 1; haystack != needle[0]; i++)

                        ;

...
snowboy9859 发表于 2011-08-27 14:28



    這块邏輯有問題,最好的結果是程序崩潰。要做如下修改:

  1.                 for (i = pos + 1; haystack[i] && haystack[i] != needle[0]; i++)
  2.                         ;

  3.                 if (haystack[i] == '\0')
  4.                         return NULL;
复制代码
同時 testcase 也要加一項。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP