C - 处理字符串的简单链接列表程序

时间:2015-06-13 18:07:13

标签: c linked-list iteration c-strings

程序规范非常简单,只需读入单词的输入文件,然后创建一个链接列表,其中每个节点都包含整个字符串。

这是我的节点结构:

typedef struct wordNode{
    char *word;
    token_type type;

    struct wordNode *next;
} wordNode;

在我获得LL基础知识后,令牌类型将会发挥作用。

main的一般过程是打开输入文件,用第一个单词设置head,然后使用第二个节点指针“current”遍历输入文件的其余部分。然后,使用打印列表功能从头指针打印列表。

void printList(wordNode *head)
{
    while(head != NULL)
    {
        printf("%s ", head->word);
        head = head->next;
    }

}

int main()
{
    //Open input file
    FILE *input = fopen("input.txt", "r");
    char nextWord[12] = "";

    //Scan in first word for head node
    fscanf(input, "%s", nextWord);

    //create head, fill it in with the first word, and create current
    wordNode *head = malloc(sizeof(wordNode));
    head->next = malloc(sizeof(wordNode));
    head->word = nextWord;

    printf("%s ", head->word);
    wordNode *current = head->next;

//Begin Iteration
    while(fscanf(input, "%s", nextWord) != EOF)
    {
        current = (wordNode*)malloc(sizeof(wordNode));
        current->word = nextWord;
        current->next = NULL;
        printf("%s ", current->word);
        current = current->next;
   }

    printList(head);
 }

同时,main中的那些printfs会给我我想要的输出,所以字符串似乎在迭代期间被正确保存,但是printList函数给出的输出是重复几次的列表中的最后一个单词通过垃圾值。

我认为head在某种程度上与当前联系在一起并且不会在迭代中保持在列表的开头,但我不确定它的移动方式或原因。

另外,我应该使用strcpy将字符串保存到节点吗?我之前尝试过,但是当我尝试时它会导致崩溃。

3 个答案:

答案 0 :(得分:1)

nextWord应该是一个更大的数组(例如nextWord[200]),或者您应该限制fscanf存储的字符数,例如

fscanf(input, "%11s", nextWord);

或者使用更大的数组并限制字符数。

在将每个字符串读入nextWord数组后,您需要复制每个字符串。代码当前只是将nextWord数组的地址分配给每个word指针。因此链表中的每个节点都指向相同的字符串,这将是从文件中读取的最后一个字符串。要复制字符串,您需要分配内存,然后strcpystrdup函数会为您执行此操作,但并非所有系统都支持strdup

当代码创建head时,它为两个结构分配内存。相反,它应该为一个结构分配内存并将head->next设置为NULL。

变量current是混乱的,例如您设置current->next = NULL后两行设置current = current->next。要使代码有效,您需要两个变量,我称之为tailcurrenttail应指向链表中的最后一个节点。最初,tail指向head。创建新节点时,代码应如下所示

    current = (wordNode*)malloc(sizeof(wordNode));
    current->word = strdup( nextWord );
    current->next = NULL;
    tail->next = current;
    tail = current;

另外,请勿fscanf查看EOF。相反,请检查fscanf是否返回了预期的转化次数。原因是如果在到达文件结尾之前转换失败,fscanf可能会陷入无限循环。所以while循环应该是

while(fscanf(input, "%11s", nextWord) == 1)

答案 1 :(得分:0)

您需要为char * s分配内存:

int main()
{
//Open input file
FILE *input = fopen("input.txt", "r");
char nextWord[12] = "";

//Scan in first word for head node
fscanf(input, "%s", nextWord);

//create head, fill it in with the first word, and create current
wordNode *head = malloc(sizeof(wordNode));
head->next = malloc(sizeof(wordNode));
head->word = (char *)calloc(strlen(nextWord) + 1);
strcpy(head->word, nextWord);

printf("%s ", head->word);
wordNode *current = head->next;

//Begin Iteration
while(fscanf(input, "%s", nextWord) != EOF)
{
    current = (wordNode*)malloc(sizeof(wordNode));
    current->word = (char *)calloc(strlen(nextWord) + 1);
    strcpy(current->word, nextWord);
    current->next = NULL;
    printf("%s ", current->word);
        current = current->next;
    }

printList(head);
}

答案 2 :(得分:0)

因为您没有保存输入。只有他们的地址保存在链表中。

当您同意head->word = nextWord本地aray分配的nextWord的地址时。

您需要在结构中有足够的空间,如char Word[SIZE]或使用动态分配char *Word = malloc( SIZE ),您应该使用strcpy来复制输入。

head->word = malloc(SIZE);
strcpy(heap->word, nextWord);

还有一点错误

        wordNode *head = malloc(sizeof(wordNode));
        head->next = malloc(sizeof(wordNode)); /* (1) Allocated */
        head->word = nextWord;

        printf("%s ", head->word);
        wordNode *current = head->next; /* current points allocated memory (1) */

    //Begin Iteration
        while(fscanf(input, "%s", nextWord) != EOF)
        {
            current = (wordNode*)malloc(sizeof(wordNode)); /*re-allocation 
and (1) is allocated but not used memory you can not access it anymore*/
            current->word = nextWord;
            current->next = NULL;
            printf("%s ", current->word);
            current = current->next;
       }

        printList(head);
     }