【问题标题】:Substrings in the middle of a String in CC中字符串中间的子字符串
【发布时间】:2015-06-28 19:54:44
【问题描述】:

我需要提取我知道的字符串之间的子字符串。

我有类似char string = "abcdefg"; 我知道我需要在"c""f" 之间,那么我的回报应该是"de"

我知道strncpy() 函数,但不知道如何在字符串中间应用它。

谢谢。

【问题讨论】:

  • 显示您的尝试,以便我们更正您的代码
  • 这个定义是错误的char string = "abcdefg".
  • 我们需要确切地知道你有什么,而不是喜欢你有什么。
  • 检查函数: const char * strstr ( const char * str1, const char * str2 );这基本上就是你所需要的。我们将等待您的代码的更新版本 :-)
  • 阅读strchr。和/或strpos

标签: c string substring extract strncpy


【解决方案1】:

这是一个完整的工作示例:

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

int main(void) {
    char string[] = "abcdefg";

    char from[] = "c";
    char to[]   = "f";

    char *first = strstr(string, from);

    if (first == NULL) {
        first = &string[0];
    } else {
        first += strlen(from);
    }

    char *last = strstr(first, to);

    if (last == NULL) {
        last = &string[strlen(string)];
    }

    char *sub = calloc(strlen(string) + 1, sizeof(char));

    strncpy(sub, first, last - first);

    printf("%s\n", sub);

    free(sub);

    return 0;
}

您可以通过this ideone查看。

现在,解释:

1.

    char string[] = "abcdefg";

    char from[] = "c";
    char to[]   = "f";

字符串的声明:要检查的主字符串,开始分隔符,结束分隔符。请注意,这些也是数组,因此 fromto 可以分别为 cdfg

2.

    char *first = strstr(string, from);

在主字符串中查找开始分隔符的出现。请注意,它会找到 first 出现 - 如果您需要找到最后一个(例如,如果您有字符串 abcabc,并且您想要第二个 a 的子字符串),它可能需要不同。

3.

    if (first == NULL) {
        first = &string[0];
    } else {
        first += strlen(from);
    }

处理字符串中第一个分隔符不出现的情况。在这种情况下,我们将从整个字符串的开头创建一个子字符串。但是,如果确实出现了,我们将指针移动from 字符串的长度,因为我们需要提取从第一个分隔符之后 开始的子字符串(感谢@dau_sama 的纠正)。 根据您的规格,这可能需要也可能不需要,或者可能会出现其他结果。

4.

    char *last = strstr(first, to);

在主字符串中查找结束分隔符的出现。请注意,它会找到 first 的出现。

正如@dau_sama 所指出的,最好从first 搜索结束分隔符,而不是从整个字符串的开头。这可以防止出现to 早于from 的情况。

5.

    if (last == NULL) {
        last = &string[strlen(string)];
    }

处理第二个分隔符没有出现在字符串中的情况。在这种情况下,我们将创建一个子字符串直到字符串结束,因此我们得到一个指向最后一个字符的指针。 同样,根据您的规格,这可能需要也可能不需要,或者可能会出现其他结果。

6.

    char *sub = calloc(last - first + 1, sizeof(char));

    strncpy(sub, first, last - first);

根据之前找到的指针分配足够的内存并提取子字符串。我们从first 字符开始复制last - first(子字符串的长度)字符。

7.

    printf("%s\n", sub);

这是结果。

我希望它确实提供了足够详细的问题。根据您的具体规格,您可能需要以某种方式进行更改。例如,如果您需要查找 所有 个子字符串,而不仅仅是第一个,您可能需要创建一个循环来查找 firstlast

【讨论】:

  • 如果您检查我的存根答案,从那里获得灵感,您会发现您的方法存在问题。 char *first = strstr(string, from); char *last = strstr(string, to); last 可以是
  • 你也不需要分配这么大的字符串: char *sub = calloc(strlen(string) + 1, sizeof(char)); (last - first)+1 就够了
  • 是的。也包括在答案中。
  • 另外,如果模式长于一个字符,您的代码将不起作用,strstr 在匹配的字符串之后返回一个指针! :-)
【解决方案2】:

TY 伙计们,使用以下表格工作:

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

char *between_substring(char *str, char from, char to){
while(*str && *str != from)
    ++str;//skip
if(*str == '\0')
    return NULL;
else
    ++str;

char *ret = malloc(strlen(str)+1);
char *p = ret;
while(*str && *str != to){
    *p++ = *str++;//To the end if `to` do not exist
}
*p = 0;
return ret;
}

int main (void){
char source[] = "abcdefg";
char *target;
target = between(source, 'c', 'f');
printf("%s", source);
printf("%s", target);

return 0;   
}

【讨论】:

    【解决方案3】:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *between(const char *str, char from, char to){
        while(*str && *str != from)
            ++str;//skip
        if(*str == '\0')
            return NULL;
        else
            ++str;
    
        char *ret = malloc(strlen(str)+1);
        char *p = ret;
        while(*str && *str != to){
            *p++ = *str++;//To the end if `to` do not exist
        }
        *p = 0;
        return ret;
    }
    
    int main(void){
        const char* string = "abcdefg";
        char *substr = between(string, 'c', 'f');
    
        if(substr!=NULL){
            puts(substr);
            free(substr);
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案4】:

      由于人们似乎不理解我在 cmets 中的方法,这里有一个快速破解的存根。

      const char* string = "abcdefg";
      const char* b = "c";
      const char* e = "f";
      //look for the first pattern
      const char* begin = strstr(string, b);
      if(!begin)
        return NULL;
      //look for the end pattern
      const char* end = strstr(begin, e);
      if(!end)
        return NULL;
      end -= strlen(e);
      
      char result[MAXLENGTH];
      strncpy(result, begin, end-begin);
      

      【讨论】:

      • 为什么是end -= strlen(e)
      • 因为第二个模式可能长于 1 个字符,并且 strstr 在整个字符串匹配后返回指针。如果你有: const char* e = "fad" 并且在你的字符串中: "fadeee",它会返回一个指向第一个 "e" 的指针,但是如果你想删除 whle 字符串,你需要将它向左移动.
      猜你喜欢
      • 2012-12-29
      • 2013-12-11
      • 2015-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多