我正在尝试从文件中读取数据并将数据保存到链接列表中。 我们无法将char单词变成静态char。 我们必须使其动态以使用char * word接受任何长度的单词。 我无法从文件中读取单词并将其保存到动态字符中。 我之前用static char做到了,这很容易。 这是代码。

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

struct node {
    char *word;
    struct node *next;
};

struct codex {
    char *word;
    struct codex *next;
};

struct node *loadWords(FILE *stream);

int main() {
    struct node *head;
    FILE *stream;
    head = loadWords(stream);
    return 0;
}

struct node *loadWords(FILE *stream) {
    struct node *poem;
    struct node *temp;
    char *words, *currentWord;
    size_t chrCount;
    stream = fopen("hw8.data", "r");

    rewind(stream);

    while(!feof(stream)) {
        if(temp = (struct node*)calloc(1, sizeof(struct node)) == NULL) {
            printf("ERROR - Could not allocate memory.\n");
            exit(0);
        }
        getline(&words, &chrCount, stream);
        currentWord = strtok(words, " ");
        strcpy(temp->word, words);
        head->next = temp;
        head = head->next;
    }

    return poem;
}

我如何动态地做到这一点?

#1楼 票数:0

由于您似乎知道如何分配内存,因此我假设问题是您不知道每个单词分配多少内存。 (类似的想法适用于逐行阅读)。

如果您对每个单词的大小有一些了解,可以静态分配,然后在读完每个单词后,动态分配所需的正确大小。

否则,您可以一次读入一个字符,直到完成一个单词为止,以便可以根据需要增加缓冲区。

#2楼 票数:0 已采纳

这使用getline从文件中读取每一行。 如果将words设置为NULL并将chrCount设置为零,则getline将分配存储文件中的行所需的内存。
在标记该行时,将调用一个结构。 strdup将分配内存以存储令牌并将令牌复制到结构中。
新结构将添加到链接列表的末尾。 释放分配给单词的内存,并为下一行重置单词和chrCount。
只要getline返回的值大于0,循环就会继续。
通常,遍历列表会打印每个单词,然后再次遍历该列表,以释放分配的内存。

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

struct node {
    char * word;
    struct node* next;
};

struct node *loadWords(FILE *stream);

int main()
{
    FILE *stream = NULL;
    struct node *head;
    struct node *temp;
    struct node *loop;
    head = loadWords(stream);
    if ( head == NULL) {
        return 1;
    }
    temp = head;//print each word
    while ( temp != NULL) {
        printf ( "%s\n", temp->word);
        temp = temp->next;
    }

    temp = head;// free memory
    while ( temp != NULL) {
        loop = temp->next;
        free ( temp->word);
        free ( temp);
        temp = loop;
    }
    return 0;
}

struct node *loadWords(FILE *stream) {
    struct node *loop = NULL;
    struct node *temp = NULL;
    struct node *head = NULL;
    char *words = NULL;
    char *currentWord;
    size_t chrCount = 0;
    if ( ( stream = fopen("hw8.data", "r")) == NULL) {
        printf ("could not open file\n");
        return NULL;
    }

    while( getline( &words, &chrCount, stream) > 0) {//read a line from file
        currentWord = strtok(words, " ");//get first token
        while ( currentWord != NULL) {//loop through tokens
            if((temp = calloc(1, sizeof(struct node))) == NULL) {
                printf("ERROR - Could not allocate memory.\n");
                exit(0);
            }
            temp->word = strdup ( currentWord);//allocate memory and copy token to word
            if ( head == NULL) {
                head = temp;//first structure
            }
            else {
                loop = head;
                while ( loop->next != NULL) {//loop to last structure
                    loop = loop->next;//add structure to end
                }
                loop->next = temp;
            }
            currentWord = strtok(NULL, " ");//next token
        }
        free ( words);//release memory
        chrCount = 0;//so readline will allocate memory for next line
        words = NULL;
    }
    fclose ( stream);
    return head;
}

#3楼 票数:0

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

struct node {
    char *word;
    struct node *next;
};

//struct codex unused

struct node *loadWords(FILE *stream);

int main(void) {
    struct node *head;
    FILE *stream = fopen("hw8.data", "r");//No sense to pass arguments If you do not open at caller side
    head = loadWords(stream);
    fclose(stream);
    {//test print and release
        struct node *p = head;
        while(p){
            struct node *temp = p->next;
            puts(p->word);
            free(p->word);
            free(p);
            p = temp;
        }
    }
    return 0;
}

struct node *loadWords(FILE *stream) {
    struct node *head = NULL, *curr, *temp;
    char *words = NULL, *currentWord;
    size_t chrCount = 0;

    rewind(stream);

    while(getline(&words, &chrCount, stream) != -1){
        currentWord = strtok(words, " \t\n");
        while(currentWord != NULL){
            if((temp = calloc(1, sizeof(struct node))) == NULL) {
                fprintf(stderr, "ERROR - Could not allocate memory.\n");
                exit(EXIT_FAILURE);
            }
            temp->word = strdup(currentWord);//malloc and strcpy
            if(head == NULL){
                curr = head = temp;
            } else {
                curr = curr->next = temp;
            }
            currentWord = strtok(NULL, " \t\n");
        }
    }
    free(words);

    return head;
}

#4楼 票数:-1

解释这个想法:

我的想法是将每个单词的字符链接到名为Word的链接列表中。 然后,我将每个单词放在另一个名为Node链接列表中。 (当然,所有内容都将动态分配)。

文本示例:

你好世界,在这里。

我们的算法将执行以下操作:

H->e->l->l->o > W->o->r->l->d > h->e->r->e

注意 :单词由空格或标准标点分隔,因此我使用了isspaceispunct函数。

这是我的代码:

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include <ctype.h>
struct Node {
    char * word;
    struct Node* next;
};

struct Word {
    char chr;
    struct Word* next;
};


int main (void)
{
   static const char filename[] = "C:\\a.txt";
   FILE *file = fopen(filename, "r");
   Node *list = 0;
   Node **last = &list;
   Word *word = 0;
   int list_size = 0;
   int word_size = 0;
   if ( file != NULL )
   {
      int ch, inword = 0;
      while ( 1 )
      {
         ch = fgetc(file);
         if ( isspace(ch) || ispunct(ch) || ch == EOF )
         {
            if ( inword )
            {
               inword = 0;
               char * string = (char *) malloc(word_size+1);
               for(int i=word_size-1; i>=0; i--) {
                   string[i]= word->chr;
                   Word * aux = word;
                   word = word->next;
                   free(aux);
               }
               string[word_size] = '\0';
               Node * aux = (Node *) malloc(sizeof(Node));
               aux->word = string;
               aux->next = 0;
               *last = aux;
               last = & aux->next;
               word_size = 0;
            }
            if(ch == EOF)
                break;
         }
         else
         {
            inword = 1;
            Word * aux = word;
            word = (Word *) malloc(sizeof(Word));
            word->chr = ch;
            word->next = aux;
            word_size++;
         }
      }
      fclose(file);
      for(Node * aux = list ; aux; aux=aux->next) {
          puts(aux->word);
      }
      getchar();
   }
   return 0;
}

希望我能帮上忙。

快乐编码:D

  ask by user1881401 translate from so

未解决问题?本站智能推荐:

1回复

将char发送到C中的链接列表

非常感谢,现在程序运行正常。 还是我想了解一些东西,我收到2条警告: | 36 |警告:内置函数'strcspn'不兼容的隐式声明[默认启用] | | 55 |警告:内置函数'strcpy'不兼容的隐式声明[默认启用] |
3回复

C中字符的链接列表

我正在尝试创建一个保存字符类型数据的链表。 由于某些原因,该代码无法正常工作。 GCC编译器针对函数“ add_bottom_ListEl”的警告为 “警告:传递'add_bottom_listEl'的参数2会使指针不经过强制转换而成为整数” 和 “注:预期为'char
2回复

链表中char,char *之间的区别

我创建了一个包含int和char类型数据的链表。 一个函数将数据添加到列表,其他函数将其打印出来。 当我只打印int类型时,我没有任何问题,但是当我尝试也打印char类型时,程序崩溃了。 因此,它必须按照我在打印函数print_list()中定义char *的方式进行操作。 更具
1回复

从用户链接列表中扫描字符

我应该编写一个函数来扫描用户的输入,直到输入并将其输入到链表中。 我不能把它扫描成一个字符串,而不是把它放在一个列表中。 我写了这段代码,没有将字符输入到链表中,也没有从控制台退出,直到我按下退出。
2回复

从C中的链接列表中删除多个“关键”节点

我在C语言中,需要删除链表中多次出现的“键”字符并返回链表的开头。 仅当“键”不是链接列表的第一个或最后一个节点“字符”时,此功能才能正常工作。 示例…使用键“ a” 同样,任何带有“键”的立即重复的操作都会失败。 示例…使用键“ a” - - - - - - - -
1回复

在链接列表C中插入字符串或字符

我想了解如何正确地将某个字符串存储到链接列表中。 例如,定义列表: 定义正确吗? 还是我应该插入一个指向char的指针? 例如char *pc ? 问题是如何正确存储姓氏,如果我必须在“代码”中插入一个值,这相对简单,因为我只是简单地声明了一个指针“ aux”,然后a
2回复

防止链表中的char *更改

好的,所以在我的程序中,我有一个主要功能,可以将字符串输入到缓冲区(char buffer [20])中。 它将它作为char *传递给创建链接列表结构的函数,将结构的char *值设置为等于输入文本char *,然后返回struct指针并将其放在我的列表的前面。 现在,当我输入另一个字符串
1回复

如何完成“信件”功能? (链接列表)

我是链表的初学者,希望有人能帮助我。 作业需要:输入字符串(来自用户),将其存储在链接列表中,并对出现的字母计数。 例如:input:hello输出:hello h:1 e:1 l:2 o:1。 我现在有下面的代码,我想对“字母”功能有所帮助。 谢谢!