2012-05-14 2 views
1

У меня проблема при использовании strtok, и я не знаю, есть ли проблема на strtok или что-то еще.C add strtok to char *

У меня есть .txt файл с данными, как это:

sometextdada;othertextdata 
yetmoredata;andmoredata 

Считанные данные должны храниться в struct определенной следующим образом:

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

Если я делаю это:

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 работает должным образом и сохраняет sometextdada в eq.name и othertextdata в eq.teamPlace

Теперь я хочу заменить, что printf с функцией, которая добавляет eq в связанный список, который определен следующим образом:

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

Так что заменить printf на addNodeTeamsSorted(headEquipas,&tailEquipas,eq);

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

addNodeTeamsSorted(headEquipas,&tailEquipas,eq); 

Теперь, если я распечатаю связанный список, я вижу, что мой узел добавлен, но name и teamPlace содержит мусорные символы. Но если я это сделать:

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

addNodeTeamsSorted(headEquipas,&tailEquipas,eq); 

Я могу видеть, что все работает, как ожидалось, так что заставляет меня думать, что проблема, когда Строка char на мой struct

Что я делаю неправильно?

+2

'fgets (buffer, 100, equipas)! = NULL);' что? – FatalError

+1

@FatalError, иронично, что ваше имя появляется после «что?», Учитывая ваш комментарий :) –

+0

Пожалуйста, внесите свой код для addNodeTeamSorted, а также для функции, которая выводит список – Jay

ответ

2

strtok действует на буфер, указанный вами в the first call. Вместо того, чтобы хранить возвращаемые указатели напрямую (что указывает на buffer, что вы перезаписываете при обработке каждой строки), вам необходимо сделать копию строки (например, strncpy())

+0

Я сделал 'strcpy (eq.name, strtok (buffer,"; \ n ")); зЬгср (э.teamName, strtok (NULL, "; \ п")); printf ("% s% s \ n", eq.name, eq.teamPlace); addNodeTeamsSorted (headEquipas, & tailEquipas, eq); 'и может видеть, что' printf' показывает, что ожидается, но после вызова 'addNodeTeamsSorted (headEquipas, & tailEquipas, eq);' только текст 'eq.name' напечатан как ожидается. 'eq.teamPlace' печатает другую вещь – Favolas

+0

Сначала вам нужно выделить память для' name' и 'teamPlace', прежде чем вы выполните строковое копирование (иначе вы либо записываете в память, не принадлежащую вам, либо перезаписываете другие части Память). Кроме того, как минимум, используйте 'strncpy' вместо' strcpy', чтобы предотвратить переполнение буфера, когда вход слишком велик ('strcpy' не проверяет, достаточно ли места для копирования) – Attila

+0

Спасибо. Следуя вашему предложению и заставил его работать должным образом. Большое спасибо – Favolas

2

Ваша проблема в том, что ваш буфер создан в стеке, а результаты strtok указывают на буфер.

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

Попробуйте использовать функцию strdup() на выходе strtok() и сохранить их в своей структуре; это скопирует строки, возвращенные strtok() в кучу, где они не будут перезаписаны неожиданно.