Завершите переписывание этого ответа, чтобы устранить некоторые принципиально неправильные вещи, которые я не видел в первый раз.См. Встроенные комментарии в коде внизу, чтобы объяснить некоторые изменения конструкции:
Я выполнил ваш код в точности как есть и увидел то, что вы описываете, и кроме примечания об использовании strcmp
вдругой ответ, нашел несколько строк кода, которые можно откорректировать или удалить, чтобы заставить его делать то, что вы описали, следует:
Во-первых, определение структуры создает указатель на массив char.Исходя из того, что вы делаете позже в коде, вам нужен простой массив char
typedef struct string {
//char* token[25]; //this create a pointer to array of 25 char
char token[25]; //this is all you need
} string;
. Как вы увидите позже, это значительно упростит распределение памяти.
некоторые основныепроблемы:
Включите символ новой строки \n
в свой разделитель.Когда в конце ввода строки вводится <enter>
, добавляется символ новой строки, в результате чего первый экземпляр this
и второй экземпляр this\n
будут неравными.
while((buffer = strtok(NULL, " \n")) && buffer != NULL){
^^
Эта строка создает неинициализированную память.
string* New = malloc(dim*sizeof(string));
Примечание об использовании malloc () против calloc () : malloc() оставляет память, которую он создает, неинициализированной, в то время как calloc () создает блок памяти, все инициализированные для 0
.
Память, созданная с помощью malloc()
Память, созданная с использованием calloc()
:
Это становится важным в нескольких местах вашего кода, но, в частности, я вижу проблему в последнем разделе:
for(i = 0; New->token[i] != NULL; ++i) {
printf(" %s", New->token[i]);
}
Если память создана для New
не инициализируется, вы можете получить ошибку времени выполнения, когда индекс i
увеличивается за пределы области памяти, в которую вы явно записали, и цикл пытается проверить New->token[i]
.Если New->token[i]
содержит что-либо кроме 0
, он попытается напечатать эту область памяти.
Вы также должны освободить каждый экземпляр памяти, созданный в вашем коде, с соответствующим вызовом free () .
Все это и многое другое рассматривается в следующей переписке вашего кода: (проверено это строка строка .)
typedef struct string {
//char* token[25]; //this create a pointer to array of 25 char
char token[25]; //this is all you need
} string;
int main() {
char* s;
char* buffer = NULL;
int i = 0, r = 0;
string* New = calloc(dim, sizeof(string));//Note: This creates an array of New.
//Example: New[i]
//Not: New->token[i]
s = calloc(dim , sizeof(char));
fgets(s, dim, stdin);
printf("The string is: %s\n", s);
buffer = strtok(s, " \n");
strcpy(New[i].token, buffer); //use strcpy instead of = for strings
//restuctured the parsing loop to a more conventional construct
// when using strtok:
if(buffer)
{
++i;
while(buffer){
printf("\nbuffer is: %s", buffer);
for(r = 0; r < i; ++r) {
if(strcmp(New[r].token, buffer) != 0 && r == i-1) {
strcpy(New[i].token, buffer);
++i;
}
else if(strcmp(New[r].token, buffer)==0) {
break;
}
}
buffer = strtok(NULL, " \n");
}
}
printf("\n New string: ");
for(i = 0; i<dim; i++) {
if(New[i].token) printf(" %s", New[i].token);
}
free(New);
free(s);
return 0;
}