使用链表将文件中的单词读入动态字符
Reading words from file into dynamic char with linked lists
我正在尝试从文件中读取数据并将数据保存到链表中。我们无法将字符字变成静态字符。我们必须使用 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;
}
我如何动态执行此操作?
既然你似乎知道如何分配内存,我假设问题是你不知道为每个单词分配多少内存。 (类似的想法适用于逐行阅读)。
如果您对每个单词可能有多大有一些想法,您可以静态分配它,然后在读入每个单词后,动态分配您需要的正确大小。
否则,您可以一次读一个字符,直到读完一个单词,这样您就可以根据需要增加缓冲区。
解释思路:
我的想法是 link 每个单词的字符在一个名为 Word
的 linked 列表中。然后,我将每个单词放在另一个名为 Node
的 linked 列表中。 (当然,一切都将动态分配)。
文本示例:
Hello World, here.
我们的算法会做这样的事情:
H->e->l->l->o
-> W->o->r->l->d
-> h->e->r->e
注意:单词由 space 或标准标点分隔,所以我使用了 isspace
和 ispunct
函数。
这是我的代码:
#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] = '[=10=]';
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
这使用 getline 从文件中读取每一行。如果 words
设置为 NULL 并且 chrCount
设置为零,getline 将分配存储文件中的行所需的内存。
随着行被标记化,结构被调用。 strdup
将分配内存来存储令牌并将令牌复制到结构中。
新结构被添加到链表的末尾。释放分配给字的内存,并为下一行重置字和 chrCount。
只要 getline returns 的值大于 0.
,循环就会继续
在 main 中,遍历列表打印每个单词然后再次遍历,释放分配的内存。
#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;
}
#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;
}
我正在尝试从文件中读取数据并将数据保存到链表中。我们无法将字符字变成静态字符。我们必须使用 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;
}
我如何动态执行此操作?
既然你似乎知道如何分配内存,我假设问题是你不知道为每个单词分配多少内存。 (类似的想法适用于逐行阅读)。
如果您对每个单词可能有多大有一些想法,您可以静态分配它,然后在读入每个单词后,动态分配您需要的正确大小。
否则,您可以一次读一个字符,直到读完一个单词,这样您就可以根据需要增加缓冲区。
解释思路:
我的想法是 link 每个单词的字符在一个名为 Word
的 linked 列表中。然后,我将每个单词放在另一个名为 Node
的 linked 列表中。 (当然,一切都将动态分配)。
文本示例:
Hello World, here.
我们的算法会做这样的事情:
H->e->l->l->o
-> W->o->r->l->d
-> h->e->r->e
注意:单词由 space 或标准标点分隔,所以我使用了 isspace
和 ispunct
函数。
这是我的代码:
#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] = '[=10=]';
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
这使用 getline 从文件中读取每一行。如果 words
设置为 NULL 并且 chrCount
设置为零,getline 将分配存储文件中的行所需的内存。
随着行被标记化,结构被调用。 strdup
将分配内存来存储令牌并将令牌复制到结构中。
新结构被添加到链表的末尾。释放分配给字的内存,并为下一行重置字和 chrCount。
只要 getline returns 的值大于 0.
,循环就会继续
在 main 中,遍历列表打印每个单词然后再次遍历,释放分配的内存。
#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;
}
#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;
}