Подстроки в середине строки в C

Мне нужно извлечь подстроки, которые находятся между строками, которые я знаю.

У меня есть что-то вроде char string = "abcdefg";Я знаю, что мне нужно между "c" а также "f"тогда мое возвращение должно быть "de",

Я знаю strncpy() функция, но не знаю, как применить его в середине строки.

Спасибо.

4 ответа

Вот полный рабочий пример:

#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;
}

Вы можете проверить это в этом ideone.

Теперь объяснение:

1.

    char string[] = "abcdefg";

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

Объявления строк: проверяемая основная строка, начальный разделитель, конечный разделитель. Обратите внимание, что это тоже массивы, поэтому from а также to может быть, например, cd а также fgсоответственно.

2.

    char *first = strstr(string, from);

Найти вхождение начального разделителя в основной строке. Обратите внимание, что он находит первый случай - если вам нужно найти последний (например, если у вас была строка abcabc, а ты хотел подстроку от второго a), это, возможно, должно быть другим.

3.

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

Обработка ситуации, в которой первый разделитель не появляется в строке. В таком случае мы сделаем подстроку с начала всей строки. Однако, если он появляется, мы перемещаем указатель на длину from строка, так как нам нужно извлечь подстроку, начинающуюся после первого разделителя (исправление благодаря @dau_sama). В зависимости от ваших требований, это может или не может быть необходимо, или можно ожидать другого результата.

4.

    char *last = strstr(first, to);

Найти вхождение конечного разделителя в основной строке. Обратите внимание, что он находит первый случай.

Как отмечает @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);

Выделите достаточную память и извлеките подстроку на основе указателей, найденных ранее. Мы копируем last - first (длина подстроки) символы, начинающиеся с first персонаж.

7.

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

Вот результат.

Я надеюсь, что это представляет проблему с достаточным количеством деталей. В зависимости от ваших точных спецификаций вам может потребоваться как-то изменить это. Например, если вам нужно было найти все подстроки, а не только первую, вы можете сделать цикл поиска first а также last,

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;   
}

Так как люди, кажется, не поняли мой подход в комментариях, вот быстрый взломанный вместе заглушка.

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);
#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;
}
Другие вопросы по тегам