Как объяснено в комментарии выше, при токенизации input
с tokenS
адрес, удерживаемый tokenS
, указывает на адрес в пределах input
.Когда вы снова вызываете fgets
, все предыдущие указатели в конечном итоге указывают на новую информацию в input
, поскольку вы перезаписали то, что было в input
, при следующем вызове fgets
.
Чтобы решитьпроблема, просто выделите хранилище для tokenS
(скажем, в tokenScpy
), а затем сохраните копию в stack
и queue
.Каждый tokenScpy
будет указывать на отдельный блок памяти с выделенной продолжительностью хранения , и на него не будут влиять любые изменения, внесенные вами в input
.(вы также несете ответственность за освобождение каждого блока с памятью больше не требуется)
Если у вас есть POSIX strdup
, это может обеспечить выделение и копирование в один вызов.( но обратите внимание: strdup()
выделяет, поэтому вы должны проверить, что выделение завершается успешно, как если бы вы сами звонили malloc()
.
С помощью strdup()
вы можете сделать:
#define DELIM " \f\n\r\t\v"
FILE *fp = fopen(argv[2], "r");
char input[80];
if (fp == NULL) {
perror("Error");
exit(1);
fclose(fp);
}
Node* stack = NULL;
Node* queue = NULL;
while (fgets(input, 80, fp)) {
const char *space = DELIM;
while (tokenS != NULL) {
char *tokenScpy = strdup (tokenS);
if (!tokenScpy) { /* strdup allocate, you validate */
perror ("malloc-tokenScpy");
break;
}
printf("test %s\n", tokenScpy);
queue = enqueue(queue, tokenScpy);
stack = push(stack, tokenScpy);
tokenS = strtok(NULL, DELIM);
}
}
printf("--Queue--\n");
printList(queue);
printf("--Stack--\n");
printList(stack);
( примечание: const char *space = " \f\n\r\t\v";
#define DELIM " \f\n\r\t\v"
использовалось вместо *1035* просто из-за того, что space
никогда не меняется, в любом случае это нормально)
Если strdup()
недоступно, тогда простой вызов malloc
и memcpy
выполнит то же самое, например,
while (tokenS != NULL) {
size_t len = strlen (tokenS);
char *tokenScpy = malloc (len + 1);
if (!tokenScpy) { /* validate every allocation */
perror ("malloc-tokenScpy");
break;
}
memcpy (tokenScpy, tokenS, len + 1);
printf("test %s\n", tokenScpy);
queue = enqueue(queue, tokenScpy);
stack = push(stack, tokenScpy);
tokenS = strtok(NULL, DELIM);
}
Примечание: , как указывает г-н Леффлер, оба queue
и stack
будут хранить одну и ту же копию tokenScpy
, что хорошо, если для каждого указателя вызывается только один free()
. Если ваши стек и очередь у каждой подпрограммы есть свои free()
сохраненных указателей - вам нужно будет сделать вторую копию каждого токена, чтобы у каждого была своя собственная копия. В этом случае вы могли бы сделать что-то похожее на:
while (fgets(input, 80, fp)) {
const char *space = DELIM;
while (tokenS != NULL) {
char *tokenScpys = strdup (tokenS),
*tokenScpyq = strdup (tokenS);
/* strdup allocate, you validate */
if (!tokenScpys || !tokenScpyq) {
perror ("malloc-tokenScpys/tokenScpyq");
break;
}
printf("tests %s testq %s\n", tokenScpys, tokenScpyq);
queue = enqueue(queue, tokenScpyq);
stack = push(stack, tokenScpys);
tokenS = strtok(NULL, DELIM);
}
}