HxH HxH - 1 month ago 6
C Question

How to store values with same memory location in c?

If I have a file stream with content

123 1234

1223 124235

21432 325


In my program I read line by line of the file and store the first target of each line into my list. These line with same location and when I run the program it will keep pointing to the most recent data and place it in to list. Which means If I have a function called printL() in while loop. It will print

123/

1223/1223/

21432/21432/21432/


instead of

123/

123/1223/

123/1223/21432


#include <stdio.h>
#include <string.h>
#include <stdlib.h>


typedef struct n{
char *value;
struct n *next;
} Node;


void printList(Node *head){
Node *cur = head;
while(cur!=NULL){
printf("%s/", cur->value);
cur = cur->next;
}
printf("\n");
}

void insertIntoList(Node **head, char *data){
Node *newNode = malloc(sizeof(Node));
if (newNode == NULL){
perror("Failed to allocate a new node for the linked list");
exit(1);
}
newNode->value = data;
newNode->next = NULL;

Node *currentList = *head;
if(*head == NULL){ //if the linked list head is null, then add the target into linked list
*head = newNode;
}
else{
while(currentList->next!=NULL){
currentList = currentList->next;
}
currentList->next = newNode;
}
}


int main(int argc, char**argv){
FILE *fileStream;


size_t len = 0;
char *line = NULL;
Node *head = NULL;


int j;
for(j=1; j<argc-2;j++){
fileStream = fopen(argv[j], "r");
if(fileStream == NULL){
fprintf(stderr, "could not open");
continue;
}
insertIntoList(&head,"a"); /////////////Line 95
insertIntoList(&head,"b");
insertIntoList(&head,"c");
insertIntoList(&head,"d");
printf("here is a try\n");
printList(head);
while(getline(&line, &len, fileStream)!=EOF){ /////////////Line 101
char *targetNum = strtok(line, " \t\r\n");
printf("*****%s\n", targetNum);
insertIntoList(&head, targetNum);
printf("######print head here is##########\n");
printList(head);
printf("######print head here is##########->\n");
}
//printList(head);
}
return 0;
}



Answer

In order to keep the content of each loaded field returned from strtok(), just add a strdup() before calling insertIntoList() after checking if not a null-pointer.

In your code, if you compare the value of both line and targetNum are the same. If fact, the strtok() function returns a pointer to the input string and keep the pointer for the next argument.

Replace the following code:

    char *targetNum = strtok(line, " \t\r\n");
    printf("*****%s\n", targetNum);
    insertIntoList(&head, targetNum);

By that one:

    char *targetNum = strtok(line, " \t\r\n");
    if (targetNum != NULL) {
        printf("*****%s\n", targetNum);
        insertIntoList(&head, strdup(targetNum));
    }