Дважды разделенный в C

Хорошо. Например, у меня есть эта строка в моем txt файле:

1|1,12;7,19;6,4;8,19;2,2
Как Вы видите, это имеет 2 части, разделенные |. У меня нет проблем при получении обеих частей и разделении второй части 1,12;7,19;6,4;8,19;2,2 использование ; разделитель. НО у меня действительно есть проблемы с разделением далее , получить первое и второе количество каждого набора.

Это - мой текущий код:

  result = strtok(result, ";");

  while(result != NULL ) {
      printf("%s\n", result);
      result = strtok(NULL, ";");
  }

Это производит меня:

1,12
7,19
6,4
8,19
2,2

Хорошо, большой. Но когда я пробую к 'strtok' (я использую этот метод для разделения) как это:

 result = strtok(result, ";");

 while(result != NULL ) {
     //printf("%s\n", result);
     help    = strtok(result, ",");    
     while(help != NULL) {
         printf("<%s>", help);
         help = strtok(NULL, ",");
     }

     result  = strtok(NULL, ";");
 }

Я только добираюсь" <1>, <12>" как существует только один набор в этом наборе чисел. Я не понимаю, где остальная часть является числами. Вместо этого вывод должен быть: <1>, <12>, <7>, <19>, <6>, <4>, <8>, <19>, <2>, <2>. Мог кто-то давать решение, как получить КАЖДОЕ количество каждого набора этот набор чисел. Возможно, существуют другие методы, или я делаю что-то не так :)

Спасибо!

7
задан N 1.1 10 April 2010 в 09:48
поделиться

5 ответов

char *strtok(char *str, const char *delim); (из man pages)
Аргумент delim задает набор символов, разделяющих лексемы в разбираемой строке. Вызывающая сторона может указать разные строки в delim в последовательных вызовах, разбирающих одну и ту же строку.

Итак, используйте оба ; и , в качестве разделителя, чтобы получить все числа.

//this will delimit result whenever ";" or "," is found
result = strtok(result, ";,"); 

while(result != NULL ) {
    printf("%s\n", result);
    result = strtok(NULL, ";,");
}
3
ответ дан 6 December 2019 в 23:03
поделиться

Первый strtok разбивает оригинал на несколько строк с нулевым окончанием. Второй strtok применяется только к первой из этих строк - он останавливается на первом нуль-терминаторе, созданном первым вызовом strtok. Вам нужно вызвать код второго strtok для КАЖДОЙ из строк, созданных первым вызовом.

1
ответ дан 6 December 2019 в 23:03
поделиться

Как отмечали другие, strtok() не является реентерабельной - она сохраняет внутреннее состояние строки, которую разбирает, поэтому ее нельзя использовать для разбора двух разных строк одновременно (что означает два разных не-NULL значения для первого аргумента, так что ваша ситуация имеет значение).

Если у вас есть реентерабельная версия strtok_r(), вы можете изменить свой код для ее использования следующим образом:

char *st_result, *st_help;
result = strtok_r(result, ";", &st_result);

while (result) {
     printf("[%s]", result);
     help = strtok_r(result, ",", &st_help);    
     while (help) {
         printf("<%s>", help);
         help = strtok_r(NULL, ",", &st_help);
     }

     result = strtok_r(NULL, ";", &st_result);
}
1
ответ дан 6 December 2019 в 23:03
поделиться

C strtok довольно злой, поскольку он изменяет исходную строку, вставляя NULL вместо ваш разделитель. Таким образом, ваш второй цикл останавливается, когда достигает NULL, вставленного внешним циклом. Вы хотите сохранить указатели на свои ; -секционные строки в другом месте, а затем strtok каждую из них отдельно.

Или, если вы действительно хотите использовать вложенные циклы, см. Здесь .

0
ответ дан 6 December 2019 в 23:03
поделиться

В дополнение к тому, что указал Нил относительно изменения исходной строки, функция strtok() не предназначена для использования во вложенном виде, как вы описали. Возможно, вам стоит изучить функцию strtok_r() или вообще отказаться от использования семейства strtok*.

6
ответ дан 6 December 2019 в 23:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: