strtok (), если разделителем является строка

Я хочу использовать strtok(), когда разделитель является строкой, например " break point "
т.е.

This is the first part. break point This is the second part

становиться:

  1. This is the first part.
  2. This is the second part

Проблема в том, что когда я включаю пробелы, это также реализуется каждым пробелом.

Вот соответствующий код:

char seps[5] = " $$$ ";
char *token;
char current[500] = {0};
int i=0;
while(fgets(current, 500, relevantFile) != NULL){
   printf("number %d:\n", i+1);
   token = strtok(current, seps);
   while(token != NULL){
      printf(token);
      printf("\n");
      token = strtok(NULL, seps);
   }
   printf("\n");
   i++;
}

когда current - "Einstein, 1900 $$$ Mozart, 1700".
Ожидаемый ответ в консоли:

number 1:
Einstein, 1900

number 2:
Mozart, 1700

но вместо этого он печатает это:

number 1:
Einstein,
1900

number 2:
Mozart,
1700

person Tzahi Leh    schedule 08.01.2016    source источник


Ответы (2)


Чтобы удалить подстроку, вы можете попробовать что-нибудь с strstr (). Найдите подстроку, которую вы хотите удалить, затем поместите туда нулевой ограничитель '\ 0' и strcat () на нем, оставшуюся после удаленной подстроки.

eg:

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

void removeSubstr (char *string, char *sub) {
    char *match;
    int len = strlen(sub);
    while ((match = strstr(string, sub))) {
        *match = '\0';
        strcat(string, match+len);
    }
}

int main(int argc, const char *argv[]) {
    char test[] = "okay/op 1234 /opdone";
    removeSubstr(test, "/op");
    puts(test);
    return 0;
}

РЕДАКТИРОВАТЬ: строка seps в вашем коде должна быть «$$$» вместо «$$$». Это решит вашу проблему.

person CodeWarrior101    schedule 08.01.2016
comment
Я хочу не удалять подстроку, а разделить строку с указанным разделителем - person Tzahi Leh; 08.01.2016
comment
ваша строка seps имеет пробелы. она должна быть $$$ вместо $$$ - person CodeWarrior101; 08.01.2016
comment
это загвоздка! Я хочу, чтобы эти пробелы были частью разделителя - person Tzahi Leh; 08.01.2016
comment
@TzahiLeh Может быть, это для вас нормально? - person Michi; 08.01.2016

Функция может выглядеть так, как показано в демонстрационной программе.

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

char * split_string( char *s, const char *delimiter )
{
    static char *p;

    if ( s ) p = s;

    size_t n = strlen( delimiter );

    if ( p && n != 0 )
    {
        while ( memcmp( p, delimiter, n ) == 0 ) p += n;
    }

    if ( !p || !*p ) return p = NULL;

    char *t = p;

    if ( n != 0 ) p = strstr( t, delimiter );

    if ( n == 0 || !p )
    {
        p = t + strlen( t );
    }
    else
    {
        *p = '\0';
        p += n;
    }

    return t;
}

int main( void )
{
    char s1[] = "This is the first part. break point This is the second part";
    char t1[] = " break point ";

    char *p = split_string( s1, t1 );

    while ( p )
    {
        puts( p );
        p = split_string( NULL, t1 );
    }
    char s2[] = "Einstein, 1900 $$$ Mozart, 1700";
    char t2[] = " $$$ ";

    p = split_string( s2, t2 );

    while ( p )
    {
        puts( p );
        p = split_string( NULL, t2 );
    }

    return 0;
}

Вывод программы:

This is the first part.
This is the second part
Einstein, 1900
Mozart, 1700
person Vlad from Moscow    schedule 08.01.2016
comment
В Visual Studio пробелы до и после $$$ остаются. Результат идентичен strtok(current, "$$$"); - person Tzahi Leh; 08.01.2016
comment
@TzahiLeh Вы ошибаетесь. Функция пропускает строку $$$ со вставленными пробелами. - person Vlad from Moscow; 08.01.2016
comment
Вот что я получил, когда запустил ваш код: \ - person Tzahi Leh; 08.01.2016
comment
@TzahiLeh Мой код правильный. Я не знаю, что вы делаете. - person Vlad from Moscow; 08.01.2016
comment
Не знаю, но мне помогли здесь - person Tzahi Leh; 13.01.2016