【问题标题】:How to add char from a stream into a node?如何将流中的字符添加到节点中?
【发布时间】:2017-03-13 00:19:36
【问题描述】:

这是我的代码。我被困在将流文件字符串添加到我的链接列表中。例如,这里我有一个名为 foo.h 的文件。在foo中,其格式如下

12345678 12345678

1233 1389732

等等。这意味着我得到文件的每一行,只读取第一个字符串并将其添加到列表中。我在第 95 行检查了添加“a/b/c/d”。它有效。所以插入功能正在工作。问题出现在第101行。不知道为什么第二行的值覆盖了第一行的值。

这意味着,当我逐步打印列表时,它会打印出来

a/b/c/d/12345678/

a/b/c/d/1233/1233/

我不知道为什么它不为第二行打印 a/b/c/d/12345678/1233?

对此有什么建议吗?

#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, " ");
          if(strcmp(targetNum, "\n")!=0&&strcmp(targetNum,"\t")!=0&&strcmp(targetNum," ")!=0){
            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;
}

【问题讨论】:

  • 一方面,您每行只调用一次strtok,因此您无法获取每行中的第二个子字符串。其次,我不明白您为什么要检查strcmp(targetNum," "),并检查\n\t,它们也可能是分隔符字符串的一部分。您已经消除了使用strtok 找到space 的任何可能性。是时候阅读strtok 手册页了?不过还没有发现更严重的问题。
  • @WeatherVane 我只想获取每行的第一个子字符串,所以我调用 strtok() 一次。 strcmp(targetNum, " ") 检查该行是否包含任何空格。
  • 那么您需要做的就是strtok(line, " \t\r\n"); 并删除周围的繁琐。指向的标记将不包含任何分隔符字符集。
  • @WeatherVane 感谢您的建议。而且我仍然不知道为什么我不能将第二行的第一个子字符串成功添加到列表中。当程序调用第一行时,可以添加第一个子字符串。但是当程序调用文件的第二行时,targetNum 也删除了前一个...
  • 请看我的回答。

标签: c linked-list stream


【解决方案1】:

原因是,您只是将 指针 存储在列表中,而不是实际数据。

前 4 个项目都有不同的内存位置,因此它们保持不同。

但是接下来的两个具有相同的内存位置,因此两者的数据相同,即放置在该位置的最新数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    相关资源
    最近更新 更多