2012-05-14 3 views
1

strtok을 사용할 때 문제가 발생했는데, 문제가 strtok이나 다른 것인지 알 수 없습니다.C strtok을 char에 덧붙입니다. *

: 나는 이렇게 할 경우

typedef struct team{ 
    char *name; 
    char *teamPlace; 
}Team; 

:

sometextdada;othertextdata 
yetmoredata;andmoredata 

읽기 데이터가 이런 식으로 정의 된 struct에 저장하는 것입니다 :

는이 같은 데이터를 .txt 파일이

char buffer[100]; 
Team eq; 
/*Read first line*/ 
fgets(buffer, 100, equipas)!= NULL); 
eq.name= strtok(buffer,";\n"); 
eq.teamPlace= strtok (NULL,";\n"); 

printf("%s %s\n", eq.name,eq.teamPlace); 

나는 strtok이 예상대로 작동하고 있으며 저장중인 것을 볼 수 있습니다.eq.name에서3210 및 othertextdata

지금은 이런 식으로 정의되어 링크 된 목록에 eq를 추가하는 기능이 printf을 대체 할 eq.teamPlace에서 :

typedef struct nodeTeam{ 
    int numberOfTeams; 
    Team team; 
    struct nodeTeam *next; 
    struct nodeTeam *prev; 
}NodeTeam; 

그래서 나는 printfaddNodeTeamsSorted(headEquipas,&tailEquipas,eq);에 의해

교체
fgets(buffer, 100, equipas)!= NULL); 
eq.name= strtok(buffer,";\n"); 
eq.teamPlace= strtok (NULL,";\n"); 

addNodeTeamsSorted(headEquipas,&tailEquipas,eq); 

이제 링크 된 목록을 인쇄하면 노드가 추가되었지만 nameteamPlace 인 것을 알 수 있습니다. 쓰레기 문자가 들어 있습니다. 하지만이 작업을 수행 할 경우 :

fgets(buffer, 100, equipas)!= NULL); 
eq.name= "test"; 
eq.teamPlace= "test2"; 

addNodeTeamsSorted(headEquipas,&tailEquipas,eq); 

나는 그 문제가 생각 날 리드 그래서 모두가 예상하고있다으로 볼 수있을 때 문자열 내 struct

내가 뭐하는 거지 잘못에 char?

+2

'fgets (buffer, 100, equipas)! = NULL); 무엇을? – FatalError

+1

@FatalError, 당신의 이름이 "what?"다음에 표시되는 것을 아이러니하게 생각하십시오. 귀하의 의견을 고려하십시오 :) –

+0

addNodeTeamSorted 및 목록을 인쇄하는 함수에 대한 코드를 게시하십시오 – Jay

답변

2

strtokthe first call에 지정한 버퍼에서 작동합니다. 반환 된 포인터를 직접 저장하는 대신 (각 줄의 처리에서 덮어 쓰는 buffer을 다시 가리킴) 문자열의 복사본을 만들어야합니다 (예 : strncpy())

+0

나는'strcpy (eq.name, strtok (buffer, "; \ n")); strcpy (eq.팀 이름, strtok (NULL, "; \ n")); printf ("% s % s \ n", eq.name, eq.teamPlace); addNodeTeamsSorted (headEquipas, & tailEquipas, eq);''eq.name'의 텍스트 만이''addNodeTeamsSorted (headEquipas, & tailEquipas, eq); ' 예상했다. 'eq.teamPlace'가 다른 것을 인쇄하고 있습니다 – Favolas

+0

문자열 복사를하기 전에 먼저'name'과'teamPlace'를위한 메모리를 할당해야합니다. 그렇지 않으면 여러분이 소유하지 않은 메모리에 쓰거나 다른 부분을 덮어 씁니다. 기억). 또한, 입력이 너무 클 때 버퍼 오버 플로우를 막기 위해'strcpy' 대신에'strncpy'를 사용하십시오 ('strcpy'는 복사본을 저장할 충분한 공간이 있는지 확인하지 않습니다) – Attila

+0

고마워요. 제안에 따라 예상대로 작동합니다. 많은 감사 – Favolas

2

버퍼가 생성된다는 문제가 있습니다 strtok의 결과는 버퍼를 가리키고있다.

이 함수에서 돌아 오거나 버퍼에서 다른 행을 읽으면 스택 (및 버퍼)이 다른 용도로 다시 사용되고 포인터가 가리키는 데이터를 덮어 씁니다. 스택이 아닌 정적 메모리 영역에 있기 때문에 상수 문자열의 경우에는 발생하지 않습니다.

strtok()의 ​​출력에서 ​​strdup() 함수를 사용하여 구조에 저장하십시오. strtok()에 의해 반환 된 문자열을 힙으로 복사합니다. 여기서 힙은 예기치 않게 덮어 쓰이지 않습니다.

관련 문제