2017-01-12 8 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 

내가 배열 DAL 의 사본을, 나는 두 번째 strtok를 수행 할 때 난 내 원래 문자열 (코드)와 DAL의 내 사본을 변경 심지어 strtok()에만 dal 배열을 전달합니다. 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 선언 'dalcopy [0] = dal [0]; ' –

+1

[mcve]를주십시오. 너무 많이 표시되지 않습니다. –

답변

2

두 가지 주요 사항은 다음과 같습니다 코멘트에 @JohnColeman 말했다으로

  1. strtok가 destrutive 기능입니다. 즉, strtok으로 전달 된 문자열 (첫 번째 인수)을 수정합니다.
  2. strtok 당신에게 문자열의 다른 부분을 가리 포인터를 제공하고 당신은 배열 dal에 저장합니다. 이제 포인터 (what @David told you 고정 가정)의 다른 유사한 배열을 만들고 code 문자열의 동일한 부분을 가리 키도록하십시오 (dal).

dal 및 문자열 code 같은 토큰 dalcopy 점. 따라서 사용자가 변경 한 사항은 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은 문자에 대한 포인터 배열이므로)이 할당은 전혀 의미가 없습니다. 당신이 염두에 두어야 fo를했습니다

+0

선언을 수정하면 앨리어싱 문제가 발생합니다. –

+0

설명에 포인터를 입력하는 것을 잊었습니다. –

+3

이것은 여러분이 묻는 문제를 확인한 완전한 컴파일 가능한 코드를 항상 게시해야하는 이유입니다. –