2016-10-30 2 views
0

내가 파일의 라인으로 라인을 읽고 내 목록에 각 행의 첫 번째 대상을 저장 내 프로그램에서 내용c에서 동일한 메모리 위치로 값을 저장하는 방법?

123 1234 

1223 124235 

21432 325 

의 파일 스트림이있는 경우. 이 줄은 같은 위치에 있으며 프로그램을 실행하면 가장 최근의 데이터를 계속 가리키고 목록에 배치합니다. 즉, while 루프에서 printL()이라는 함수가 있으면 의미합니다. 그것은 아닌 경우 확인 후 insertIntoList()를 호출하기 전에 strtok()에서 반환 단지 strdup()를 추가

123/ 

1223/1223/ 

21432/21432/21432/ 

대신

로드 된 각 필드의 내용을 유지하기 위해
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; 
} 
+0

그리고 질문은 ...? – MordechayS

+0

@MordechayS 어떻게 값을 저장해야합니까 ... "123/1223/21432"대신 "21432/21432/21432 /"와 같은 현재 값을 인쇄합니다 ... 지적한 값을 저장하는 방법을 모르겠습니다. ... – HxH

+0

'insertIntoList'코드를 추가하십시오. – MordechayS

답변

0

인쇄됩니다 널 포인터. 둘 다 linetargetNum 의 값을 비교하는 경우 코드에서

, 동일합니다. 사실, strtok() 함수는 입력 문자열 에 대한 포인터를 반환하고 다음 인수에 대한 포인터를 유지합니다.

다음 코드 교체 작성자 :

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

을 하나 :

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

strdup()는 malloc 공간을 사용할 수있는 함수라고 생각하고 있습니다. 이 함수를 호출하면 어떻게 해제합니까? char * temp = strdup (targetNum) 및 insertIntoList (& head, temp);를 추가하려고 할 때; 나는 free (temp)를 추가했다. 그러나 valgrind 디버깅을 사용할 때 메모리 누수가 발생한다. – HxH

+0

@HxH 예, strdup() 함수는 malloc()'+'strcpy()'와 동일하므로 호출해야한다. 각각의'strdup()'호출에 대해 하나의'free()'가있다. 그러나 당신의 함수'insertIntoList()'에서 malloc()을 호출하여 구조체'Node * newNode = malloc (sizeof (Node));도 해제해야합니다. 그리고 소스 코드에'fclose()'호출이 없기 때문에 또 다른 메모리 누수가 발생할 수 있습니다. 따라서 가장 좋은 점은 업데이트 된 소스 코드로 새로운 질문을하는 것입니다. –

0

당신은 당신의 목록 노드에서 문자열의 내용을 저장하지 않습니다; 문자열의 내용에 사용 된 버퍼에 대한 포인터를 저장합니다.

문자열의 내용이 어레이 C99가요 부재에 저장된

typedef struct node Node; 
struct node { 
    Node *next; 
    char data[]; 
}; 

에리스트 노드 구조를 변경 고려한다.

노드 생성자는

Node *new_node(const char *data) 
{ 
    const size_t datalen = (data) ? strlen(data) : 0; 
    Node   *result; 

    result = malloc(sizeof (Node) + datalen + 1); 
    if (!result) { 
     fprintf(stderr, "Out of memory!\n"); 
     exit(EXIT_FAILURE); 
    } 

    if (datalen > 0) 
     memcpy(result->data, data, datalen); 

    result->next = NULL; 
    result->data[datalen] = '\0'; 

    return result; 
} 

함수가 데이터의 사본에 대한 메모리를 할당하는 방법을 참조하십시오

같은 것입니다? 개인적으로

, 내가 선호하는 size 구성원이 기본적으로 strlen(data)입니다

typedef struct node Node; 
struct node { 
    Node *next; 
    size_t hash; 
    size_t size; 
    char data[]; 
}; 

같은 (당신은 또한 NUL 바이트 \0를 포함하는 바이너리 데이터를 보유 할 노드를 사용할 수 있다는 점을 제외) 및 hash 간단한 hash입니다 data에서 계산되었습니다. hash은 노드의 전체 내용을 비교하려는 경우에 유용합니다. 두 노드의 길이 나 해시가 다른 경우에는 내용이 다른 것으로 확인됩니다. 동일하면 ,을 문자별로 비교합니다 (동일하면 memcmp(node1->data, node2->data, node1->length) == 0).

Node *new_node(Node *next, const void *data, const size_t size) 
{ 
    Node *result; 

    result = malloc(sizeof (Node) + size + 1); 
    if (!result) { 
     fprintf(stderr, "new_node(): Out of memory (%zu bytes)\n", size); 
     exit(EXIT_FAILURE); 
    } 

    /* Copy and hash data using DJB2 hash (not that good, but fast) */ 
    { 
     unsigned char  *src = (unsigned char *)data; 
     unsigned char *const end = (unsigned char *)data + size; 
     unsigned char  *dst = result->data; 
     size_t    hash = 5381; 

     while (src < end) { 
      hash = hash * 33 + (size_t)(*src); 
      *(dst++) = *(src++); 
     } 

     /* Add terminator */ 
     *dst = '\0'; 
    } 

    result->next = next; 
    result->hash = hash; 
    result->size = size; 

    return result; 
} 

Node들도 예를 들어 사용될 수있다 :

상기의 생성자 (DJB2 해시를 사용) 등에 무언가 해시 테이블 (hash table).

관련 문제