1
#include<stdio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct trial{
   char *data;
   int save;
   struct trial *next;
};

struct trial *head = NULL;

int main (){
    int x, ctr, y;
    char filestr[500];
    char *data, *save, *filestr2;
    FILE *fp;
    fp = fopen("Untitled1.txt", "r");   
    printf("Count: ");
    scanf("%d", &x);
    while(x > 0){
        if(fgets(filestr, sizeof(filestr), fp) != NULL){
            data = strtok(filestr, " ");
            filestr2 = strtok(NULL, "");
            save = strtok(filestr2, "");
            printf("%s, %s", data, save);
            struct trial *link = (struct trial*) malloc(sizeof(struct trial));
            link->data = data;
            link->save = atoi(save);
            link->next = head;
            head = link;
        }
        x--;
    }
    printf("\n");
    struct trial *ptr = head;
    ctr = 0;
    while(ptr != NULL){
          printf("Data %d: %s, %d\n", ctr + 1, ptr->data, ptr->save);
          ptr = ptr->next;
          ctr++;
    }
return 0;
}
/*Untitled1.txt is as follows
dragon 12
shadow 19
spirit 6
wiser 4
civil 8
fairy 7
*/

now here goes the problem, when x = 3; it should be:
Count: 3
dragon, 12
shadow, 19
spirit, 6

Data 1: spirit, 6
Data 2: shadow, 19
Data 3: dragon, 12

But here is what happens.
Data 1: spirit, 6
Data 2: spirit, 19
Data 3: spirit, 12

why is that the save variable is moving and the *data is not? What should I add and where to place? Thanks for the help. [sorry for the unnecessary variables, it is a part of a whole]

  • Welcome to Stack Overflow! [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh May 16 '16 at 19:45
  • 2
    strtok returns a pointer pointing into filestr, link->data points into filestr, if you overwrite filestr you overwrite link->data too … use malloc+strcpy or strdup to copy the data returned by strtok into link->data – Picodev May 16 '16 at 19:47

2 Answers2

2

As explained, strtok returns a pointer pointing into its first parameter. To fix this bug copy the part you're interessed in. Simply replace

link->data = data;

with

link->data = strdup(data);

Remember to free link->data.

Picodev
  • 506
  • 4
  • 8
0

strtok doesn't allocate memory for the strings it returns. It just returns pointers into the buffer you give it. So you need to copy any data you wish to save.

The simplest fix is to change:

link->data = data;

To:

link->data = strdup(data);

It would also be a good idea to add checks for NULL return values from strtok.

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41