【问题标题】:C version of strpos and substr?C版的strpos和substr?
【发布时间】:2012-09-25 22:03:47
【问题描述】:

我真的很惊讶我找不到有效的方法来做到这一点。我已经尝试过 strstr,这是一种与 sscanf 的组合,但根据我在其他语言方面的经验,似乎没有什么能像我期望的那样工作。

我有一个字符“ABCDEFG HIJ K BEGINTheMiddleEND LMNO PQRS”。我不知道“BEGINTheMiddleEND”在字符串中的位置,我想通过查找“”的出现以等于“TheMiddle”的字符结尾BEGIN" 和 "END" 并抓住两者之间的内容。

完成此任务的最有效方法是什么(查找和子字符串)?

谢谢!

-- 根据答案进行编辑--

我试过这个:

char *searchString = "ABCDEFG HIJ K BEGINTheMiddleEND LMNO PQRS"
char *t1, *t2;
t1 = strstr(searchString, "BEGIN");
t2 = strstr(t1, "END");

但是从指针的角度来看一定有问题,因为它对我不起作用。 Strstr 只接受两个参数,所以我不确定从前一个指针开始是什么意思。我也不确定如何使用这些指针对其进行子串化,因为它们不是 strpos 返回的整数值,而是字符指针。

再次感谢。

-- 使用最终代码编辑--

对于其他任何人来说,最终的工作代码:

char *searchString = "ABCDEFG HIJ K BEGINTheMiddleEND LMNO PQRS"
char *b = strstr(searchString , "BEGIN");
char *e = strstr(b, "END");
int offset = e - b;
b[offset] = 0;

其中“b”现在等于“BEGINTheMiddle”。 (事实证明这是我在这种情况下所需要的)。

再次感谢大家。

【问题讨论】:

    标签: c string substring strpos


    【解决方案1】:

    你需要了解什么是字符串。一个 0 分隔的字符序列。

    strstr 执行它所说的:它找到给定子字符串的开头。

    因此,使用指针“BEGIN”调用 strstr 会将您带到该子字符串的位置。指向“BEGIN”的指针,前移 5 个字符指向“TheMiddle”向前移动到下一个 0 字符。通过搜索“END”可以找到结束指针,然后需要将子字符串复制到一个新的字符串数组中(或将其剪切,将“E”替换为0;或实现您自己的字符串函数不使用 0 终止字符串,因此它们可以任意重叠)。

    这可能是您仍然缺少的步骤:实际复制字符串。例如。使用

     t3 = strndup(t1, t2 - t1);
    

    获取字符串 ABCDEF0,其中 0 是实际的 0 字符。指向开头的指针指向整个字符串,指向 E 的指针仅指向“EF”。如果要获取字符串“AB”,则需要将其复制到“AB0”,或者将 C 替换为 0。

    strstr 不会为您进行复制。它只是找到了位置。如果你想要一个索引,你可以做int offset = newPosition - oldPosition;,但如果你需要继续搜索,使用newPosition指针会更容易。

    所有这些都不如例如Java中的字符串操作。除了截断字符串,据我所知,它实际上效率更高,如果你实现了 0 终止的内存布局,那就很有意义了。只有当您将字符串视为数组时,在中间某处有一个指针可能看起来很奇怪,并像常规数组一样继续使用它。这使得“sub = string + offset”成为“sub = string.substring(offset)”的 C 写法。

    【讨论】:

    • 谢谢!这让我想到了这个 code char *b = strstr(tmpLine, "BEGIN"); char *e = strstr(b, "END"); int 偏移量 = e - b; b[offset] = 0;code 其中“b”是我需要的字符串。
    • 尝试e[0] = 0 在“END”处停止。 b = strstr(..) + strlen("BEGIN")也不是很好吗?
    【解决方案2】:

    使用strstr()两次,但第二次从第一次调用strstr()返回的位置开始+strlen(BEGIN)。

    这将是有效的,因为从strstr() 返回的第一个指针将是 BEGIN 的开头,因此您不会再次查看整个字符串,而是从 BEGIN 开始并从那里;这意味着您最多只能遍历整个字符串一次

    【讨论】:

    • 我所知道的任何 C 标准中都没有 strpos 这样的功能。也许你的意思是strstr
    • 根据此输入编辑了问题,不幸的是,我仍然没有 100% 关注,因为 strstr 没有采用“start at”参数,而且我仍然不了解拉动的指针方面子串。谢谢。
    • strstr 需要一个指针。指针是“开始于”参数。并且指针可以指向你可能称之为字符串的中间的事实,它是一个字符数组,也可以提供帮助;但它应该已经包含在你的 C 教程中。
    • @Scooter 添加 strpos 不存在的评论也得到了支持;)
    • btw .. 如果从 strstr() 返回的一个指针中减去原始指针,则会得到 strpos。问题是关于 C,而不是 php
    【解决方案3】:

    我希望这会有所帮助

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int strpos(char *haystack, char *needle, int offset);
    int main()
    {
        char *p = "Hello there all y'al, hope that you are all well";
        int pos = strpos(p, "all", 0);
        printf("First all at : %d\n", pos);
        pos = strpos(p, "all", 10);
        printf("Second all at : %d\n", pos);
    }
    
    
    int strpos(char *hay, char *needle, int offset)
    {
       char haystack[strlen(hay)];
       strncpy(haystack, hay+offset, strlen(hay)-offset);
       char *p = strstr(haystack, needle);
       if (p)
          return p - haystack+offset;
       return -1;
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 2014-02-15
      • 1970-01-01
      • 2015-02-16
      • 2012-08-23
      相关资源
      最近更新 更多