2017-01-12 3 views
1

Мне нужно отделить строку от файла. String = "21:12:36 14:45:25 08:17:24" Когда я делаю strtok() и помещаю все маркеры в массив, все работает нормально, но когда я делаю strtok() второй раз, он все испортит. Пример:Почему strtok() разбивает строку, которую я даже не передавал ей?

char *p = strtok (code, " "); 
while (p != NULL){ 
    dal[i++] = p; 
    p = strtok (NULL, " "); 
} 

Выход:

dal[0] = 21:12:36 
dal[1] = 14:45:25 
dal[2] = 08:17:24 

я копия Даль массива, и когда я strtok во второй раз я изменяю свою исходную строку (код) и мою копию декалитров Даже я передаю массив dal только для strtok(). Я попытался отправить dal в LinkedList, но после второго strtok даже LinkedList изменился.

Декларация:

char *dal[20], *dalcopy[20]; 
//copying below 
for(int k = 0; k<i; k++){ 
    dalcopy[v] = dal[k]; 
    v = v+1; 
} 

Пример:

for (int j = 0; j<i; j++){ 
    char *o = strtok(dal[j], ":"); 
    while (o != NULL){ 
     for(int h = 0; h<3; h++){ 
      if(h == 0){vienas[b].Hour = atoi(o);} 
      if(h == 1){vienas[b].Min = atoi(o);} 
      if(h == 2){vienas[b].Sec = atoi(o);} 
      o = strtok (NULL, ":"); 
     }    
     b = b+1; 
    } 

Пример LinkedList:

char *p = strtok (code, " "); 
while (p != NULL){ 
    dal[i++] = p; 
    put(head, p); //puts each element to list end 
    p = strtok (NULL, " "); 
} 
printf("%s\n", show_by_index(&head, 0)); **Output == 21 after second strtok** 

Выход:

original string = 21 
dal[0] = 21 
dal[1] = 14 
dal[2] = 08 
dalcopy[0] = 21 
etc... 

Почему это происходит?

+1

На ваш вопрос не хватает ключевых битов кода. Как объявляются 'dal' и' dalcopy'? * Как * создается 'dalcopy'? Копирование массива указателей не копирует данные, на которые указывают эти указатели. Я подозреваю, что 'dalcopy' - это массив псевдонимов. –

+0

'char * dal [20], * dalcopy [20];' - dal declaration 'dalcopy [0] = dal [0];' –

+1

Пожалуйста, дайте [mcve]. Слишком много не показано. –

ответ

2

Две основные вещи, которые Вы Ф.О. иметь в виду, являются:

  1. strtok является destrutive функция как сказал @JohnColeman в комментариях. Это означает, что strtok изменяет переданную ему строку (первый аргумент).
  2. strtok дает указатели, которые указывают на различные части строки и хранить их в массиве dal. Теперь вы создаете еще один подобный массив указателей dalcopy (при условии, что вы исправили what @David told you) и заставьте их указать на те же части строки code, что и dal.

dal и dalcopy указует на одни и те же маркер струны code. Таким образом, любое изменение, которое вы им делаете, также повлияет на code, поскольку они указывают на него.

Перед strtok и все:

+--------+--------+--------+--------+ 
| dal[0] | dal[1] | dal[2] | dal[3] | ... = dal 
+--------+--------+--------+--------+ 

+------------------------------+ 
| "21:12:36 14:45:25 08:17:24" | = code 
+------------------------------+ 

После strtok и "копирование":

+--------+--------+--------+--------+ 
| dal[0] | dal[1] | dal[2] | dal[3] | ... = dal 
+--------+--------+--------+--------+ 
    ↓   ↓   ↓ 
+---------------------------------+ 
| "21:12:36\0014:45:25\008:17:24" | = code 
+---------------------------------+ 
    ↑   ↑   ↑ 
    |   \   \----\ 
+------------+------------+------------+------------+ 
| dalcopy[0] | dalcopy[1] | dalcopy[2] | dalcopy[3] | ... = dalcopy 
+------------+------------+------------+------------+ 

Как вы можете видеть, вы не копировали его, а просто создание псевдонима.

Решение должно быть strdup/malloc + strcpy жетоны.

+0

+ репутация Хорошая работа! Очень ценю это. –

1
char *dal[20], dalcopy[20]; 
//copying below 
for(int k = 0; k<i; k++){ 
    dalcopy[v] = dal[k]; 
    v = v+1; 
} 

Это не может быть правильно. Поскольку dalcopy - это массив символов, dalcopy[v] - символ. Но dal[k] не является символом (поскольку dal - это массив указателей на символы), поэтому это назначение не имеет никакого смысла.

+0

И исправление объявления просто столкнется с проблемой сглаживания. –

+0

Я забыл ввести указатель в описании. –

+3

Вот почему вы всегда должны публиковать полный, компилируемый код, который вы подтвердили, и реплицирует проблему, о которой вы просите. –

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