Подстроки в середине строки в 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;
}