2014-01-10 3 views
0

У меня есть массив символов в C, который может иметь значение, такое как /path/example/abc. Я хочу, чтобы все символы после части /path/example/ были поглощены, перераспределяя строку для своего нового размера. Есть ли стандартная функция или функция, которую вы могли бы написать, которая может это сделать? Возможно, это может быть выполнено с помощью библиотеки, такой как PCRE? Примечание: Чистый, независимый от платформы C-код будет оценен по достоинству.Pure C: обрезать все символы в строке после появления слова

Пример:

int main() 
{ 
    char str[100] = "I am a string"; 
    newStr = globbleAfter(str, "I am a"); 
    printf("%s\n", newStr); 
    return 0; 
} 

//=> "I am a" 

ответ

1

PRCE кажется излишеством для этого. Просто используйте strstr для поиска newStr внутри str. Пример:

char *gobbleAfter(char *string, char *pattern) { 
    int len; 
    char *gobbled; 
    char *pos=strstr(string, pattern); 
    if (pos==NULL) 
     return NULL; 
    if ((gobbled=malloc(len=((pos-string)+strlen(pos)+1)))==NULL) 
     return NULL; /* or maybe call an out of memory handler */ 
    memcpy(gobbled, string, len-2); 
    gobbled[len-1]='\0'; 
    return gobbled; 
} 
0

Поскольку функция, такой как PRINTF работа по нулевому терминированым строкам, то достаточно, чтобы установить первый не необходимый символ нуль. Что-то вроде str[strlen("I am a")] = 0. Однако он изменяет исходную строку. И самое главное это небезопасно - перед установкой нуля вы должны проверить, не превышает ли длина вашей подстроки больше длины исходной строки.

0

@Wojtek Surowka Без проверки шаблона в исходной строке может быть экземпляр, в котором шаблон не содержится в исходной строке. Также существует проблема, если шаблон найден с некоторым смещением внутри строки.

String = "bob is running" 
Pattern1 = "frank" 
Pattern2 = "is run" 

@Guntram Blohm После того, как вы malloc, когда вы освободите выделенную память?

, если ((проглочены = таНос (Len = ((поз-строка) + StrLen (поз) +1))) == NULL)

Этот метод основан на SRC будучи менее чем 260 персонажи. Он не изменит исходную строку.

Эта функция неверен

#define MAX_PATH 260 
char* gobbleAfter(const char* src, const char* pattern) 
{ 
    int len = strlen(pattern); 
    int cpy_len; 
    char[MAX_PATH] gobbled_string; 
    char* pos = strstr(src, pattern); 

    gobbled_string[0] = '\0'; 

    if(pos)//null check 
    { 
    cpy_len = (pos - string) + len + 1 
    if(cpy_len <= MAX_PATH) 
    { 
     memcpy(gobbled_string, src, cpy_len); 
    } 
    } 
    return gobbled_string; 
} 

, если вы не против изменения источника

char* gobbleAfter(char* src, const char* pattern) 
{ 
    char* gobbled_string = NULL; 
    char* temp = strstr(src, pattern); 
    if(temp) 
    { 
    gobbled_string = src; 
    gobbled_string[temp - src + strlen(pattern)] = '\0'; 
    } 
    return gobbled_string; 
} 
+0

Buck, ваш символ [MAX_PATH] будет выделять строку в стек, где он будет перезаписан как только вызывающая функция вызывает что-то другое. На ваш вопрос «когда я освобожу выделенную память?»: Я этого не делаю. Вызывающий отвечает за это, когда ему больше не нужна строка, очевидно, что функция не может знать, когда. Я также не могу освободить исходную строку, поскольку это, возможно, даже не было * x * alloc'ed в первую очередь. –

+0

Гунтрам, вы правы. gobbled_string будет выделено в стеке и будет перезаписано, что является моей ошибкой. Обычно, когда я создаю эти небольшие вспомогательные функции, я стараюсь держаться подальше от выделения памяти, которую я не освобождаю, поэтому пользователю не нужно отслеживать память, которую они не выделяют. – 109

+0

Вы правы, когда пытаетесь избежать этого, потому что слишком просто вводить утечки памяти таким образом. Я согласен с тем, что «пользователь должен освободить возвращенную строку, когда он перестает ее использовать» относится к документации для таких функций. К сожалению, реальной альтернативы нет, поскольку вызывающий абонент не знает длину возвращаемой строки, поэтому вы не можете просто предоставить ему строку с соответствующим распределением. Подобные вещи, вы не можете преуспеть, вы можете просто попытаться решить, какое зло является наименее. –

Смежные вопросы