我如何才能读取长度未知的行中的每个单词?

发布于 2025-01-11 08:57:03 字数 1461 浏览 1 评论 0原文

我试图使用链接列表来保存包含一段文本的文本文件中的每个单词。因此,每一行都有未知数量的单词,每个单词之间用空格分隔。我想我可以使用 strtok() 和 getline() 来阅读每个单词。但是,该程序仅读取每行的第一个单词,因此我认为可以使用循环来检测文件每行的末尾,以便读取所有单词。

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

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

//refers to the struct for linked list 
typedef struct node link;

//a function to add word to front of linked list
link *addName(char[] word, link *head){
    link *temp1;

    temp1 = (link*)malloc(sizeof(link));
    //add char type word to linked list
    temp1->word = strdup(word);
    temp1->next = word;
    head = temp1;
    return head;
}

int main(){
    FILE *fO; 
    fO = fopen("paragraph.data", "r");
    int size = 0;
    int len = 0;

    //initialize it for the getline() and strtok()
    char *line = 0;

    
    //use malloc
    line = (char*)malloc(sizeof(int));

    //loop through the file
    while(getline(&line, &size, fO) != -1){
        char *word = strtok(line, " ");
        printf("the word: %s\n", word);

        //while(there is no "\n" detected?){}
        word = strtok(NULL, " ");
        printf("the word: %s\n", word);
        //addName()
    }

}

该文件是这样的(例如缩写):

lorem ipsum
dolor
sit amet con sec
euter orci

它可以有任意数量的单词,这让我感到困惑。有谁知道如何让 while 循环检测每行的结尾? 现在它只打印出每行的第一个单词。

the name: lorem
the name: dolor
the name: sit
the name: euter 

I was trying to use a linked list to hold every word from a textfile that had a paragraph of text in it. So each line has an unknown number of words on it, each separated by a space. I thought I could use strtok() and getline() to read through each word. However, the program only reads the first word on each line, so I thought I could use a loop to detect the end of each line of the file so that all the words would be read.

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

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

//refers to the struct for linked list 
typedef struct node link;

//a function to add word to front of linked list
link *addName(char[] word, link *head){
    link *temp1;

    temp1 = (link*)malloc(sizeof(link));
    //add char type word to linked list
    temp1->word = strdup(word);
    temp1->next = word;
    head = temp1;
    return head;
}

int main(){
    FILE *fO; 
    fO = fopen("paragraph.data", "r");
    int size = 0;
    int len = 0;

    //initialize it for the getline() and strtok()
    char *line = 0;

    
    //use malloc
    line = (char*)malloc(sizeof(int));

    //loop through the file
    while(getline(&line, &size, fO) != -1){
        char *word = strtok(line, " ");
        printf("the word: %s\n", word);

        //while(there is no "\n" detected?){}
        word = strtok(NULL, " ");
        printf("the word: %s\n", word);
        //addName()
    }

}

the file is like this(shortened for eg.):

lorem ipsum
dolor
sit amet con sec
euter orci

it could have any number of words which is what makes me confused. Does anyone know how to make the while loop detect the end of each line?
Right now it just prints out the first word of every line.

the name: lorem
the name: dolor
the name: sit
the name: euter 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铜锣湾横着走 2025-01-18 08:57:03

许多问题...

  1. char[] word 不是有效的 C,并且无法编译
  2. temp1->next = word; 成功不编译 - word 是一个 char * 指针,而不是指向
  3. 您想要的节点的指针:temp1->next = head; 到链表中
  4. 将新节点链接 strtok 上循环,因此,当然,您只会获得一个[或两个]令牌。
  5. main 中,size 必须是 size_t不是 int —— getline 调用甚至无法编译。
  6. getline 确实去除换行符
  7. line 必须在循环结束时释放
  8. 您的代码调用 < main 中的 code>addName
  9. 不要强制转换 malloc 的返回值:我是否强制转换 malloc 的结果?

在下面的代码中,我使用 < code>cpp 条件来表示旧代码与新代码:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

这是重构的代码。我已将 link 更改为 node 以更具描述性。它带有错误和修复注释:

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

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

//a function to add word to front of linked list
// NOTE/BUG: char[] isn't valid C and won't compile
#if 0
node *
addName(char[] word, node *head)
#else
node *
addName(const char *word, node *head)
#endif
{
    node *temp1;

    temp1 = malloc(sizeof(*temp1));

    // add char type word to linked list
    temp1->word = strdup(word);
// NOTE/BUG: word [corrected] is a char* and can't be assigned to next
#if 0
    temp1->next = word;
#else
    temp1->next = head;
#endif
    head = temp1;

    return head;
}

int
main()
{
    FILE *fO;

    fO = fopen("paragraph.data", "r");
// NOTE: bug size must be size_t or the getline won't compile
#if 0
    int size = 0;
#else
    size_t size = 0;
#endif
    int len = 0;

    // initialize it for the getline() and strtok()
#if 0
    char *line = 0;
#else
    char *line = NULL;
#endif

    // use malloc
// NOTE/BUG: getline expects a null pointer if size is 0
#if 0
    line = (char *) malloc(sizeof(int));
#endif

    // loop through the file
#if 0
    while (getline(&line, &size, fO) != -1) {
        char *word = strtok(line, " ");

        printf("the word: %s\n", word);

        // while(there is no "\n" detected?){}
        word = strtok(NULL, " ");
        printf("the word: %s\n", word);
        // addName()
    }
#else
    node *head = NULL;

    while (getline(&line, &size, fO) != -1) {
        // strip newline
        line[strcspn(line,"\n")] = 0;

        char *word = strtok(line," ");

        while (word != NULL) {
            printf("DEBUG: %s\n", word);
            head = addName(word,head);
            word = strtok(NULL," ");
        }
    }

    // must be freed at end
    free(line);

    // print linked list
    for (node *cur = head;  cur != NULL;  cur = cur->next)
        printf("Final: %s\n",cur->word);
#endif

    return 0;
}

这是完全清理的代码:

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

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

//a function to add word to front of linked list
node *
addName(const char *word, node *head)
{
    node *temp1;

    temp1 = malloc(sizeof(*temp1));

    // add char type word to linked list
    temp1->word = strdup(word);
    temp1->next = head;
    head = temp1;

    return head;
}

int
main()
{
    FILE *fO;

    fO = fopen("paragraph.data", "r");
    size_t size = 0;
    int len = 0;

    // initialize it for the getline() and strtok()
    char *line = NULL;

    // loop through the file
    node *head = NULL;

    while (getline(&line, &size, fO) != -1) {
        // strip newline
        line[strcspn(line,"\n")] = 0;

        char *word = strtok(line," ");

        while (word != NULL) {
            printf("DEBUG: %s\n", word);
            head = addName(word,head);
            word = strtok(NULL," ");
        }
    }

    // must be freed at end
    free(line);

    // print linked list
    for (node *cur = head;  cur != NULL;  cur = cur->next)
        printf("Final: %s\n",cur->word);

    return 0;
}

对于您的示例输入,这里是程序输出:

DEBUG: lorem
DEBUG: ipsum
DEBUG: dolor
DEBUG: sit
DEBUG: amet
DEBUG: con
DEBUG: sec
DEBUG: euter
DEBUG: orci
Final: orci
Final: euter
Final: sec
Final: con
Final: amet
Final: sit
Final: dolor
Final: ipsum
Final: lorem

A number of issues ...

  1. char[] word is not valid C and won't compile
  2. temp1->next = word; won't compile -- word is a char * pointer and not a pointer to a node
  3. You want: temp1->next = head; to link the new node into the linked list
  4. You're not looping on strtok, so, of course, you'll only get one [or two] tokens.
  5. In main, size must be a size_t and not an int -- the getline call won't even compile.
  6. getline does not strip the newline
  7. line must be freed at the end of the loop
  8. Your code does not call addName in main
  9. Don't cast the return of malloc: Do I cast the result of malloc?

In the code below, I use cpp conditionals to denote old vs. new code:

#if 0
// old code
#else
// new code
#endif

#if 1
// new code
#endif

Here is the refactored code. I've changed link into node to be more descriptive. It is annotated with bugs and fixes:

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

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

//a function to add word to front of linked list
// NOTE/BUG: char[] isn't valid C and won't compile
#if 0
node *
addName(char[] word, node *head)
#else
node *
addName(const char *word, node *head)
#endif
{
    node *temp1;

    temp1 = malloc(sizeof(*temp1));

    // add char type word to linked list
    temp1->word = strdup(word);
// NOTE/BUG: word [corrected] is a char* and can't be assigned to next
#if 0
    temp1->next = word;
#else
    temp1->next = head;
#endif
    head = temp1;

    return head;
}

int
main()
{
    FILE *fO;

    fO = fopen("paragraph.data", "r");
// NOTE: bug size must be size_t or the getline won't compile
#if 0
    int size = 0;
#else
    size_t size = 0;
#endif
    int len = 0;

    // initialize it for the getline() and strtok()
#if 0
    char *line = 0;
#else
    char *line = NULL;
#endif

    // use malloc
// NOTE/BUG: getline expects a null pointer if size is 0
#if 0
    line = (char *) malloc(sizeof(int));
#endif

    // loop through the file
#if 0
    while (getline(&line, &size, fO) != -1) {
        char *word = strtok(line, " ");

        printf("the word: %s\n", word);

        // while(there is no "\n" detected?){}
        word = strtok(NULL, " ");
        printf("the word: %s\n", word);
        // addName()
    }
#else
    node *head = NULL;

    while (getline(&line, &size, fO) != -1) {
        // strip newline
        line[strcspn(line,"\n")] = 0;

        char *word = strtok(line," ");

        while (word != NULL) {
            printf("DEBUG: %s\n", word);
            head = addName(word,head);
            word = strtok(NULL," ");
        }
    }

    // must be freed at end
    free(line);

    // print linked list
    for (node *cur = head;  cur != NULL;  cur = cur->next)
        printf("Final: %s\n",cur->word);
#endif

    return 0;
}

Here is the fully cleaned up code:

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

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

//a function to add word to front of linked list
node *
addName(const char *word, node *head)
{
    node *temp1;

    temp1 = malloc(sizeof(*temp1));

    // add char type word to linked list
    temp1->word = strdup(word);
    temp1->next = head;
    head = temp1;

    return head;
}

int
main()
{
    FILE *fO;

    fO = fopen("paragraph.data", "r");
    size_t size = 0;
    int len = 0;

    // initialize it for the getline() and strtok()
    char *line = NULL;

    // loop through the file
    node *head = NULL;

    while (getline(&line, &size, fO) != -1) {
        // strip newline
        line[strcspn(line,"\n")] = 0;

        char *word = strtok(line," ");

        while (word != NULL) {
            printf("DEBUG: %s\n", word);
            head = addName(word,head);
            word = strtok(NULL," ");
        }
    }

    // must be freed at end
    free(line);

    // print linked list
    for (node *cur = head;  cur != NULL;  cur = cur->next)
        printf("Final: %s\n",cur->word);

    return 0;
}

For your sample input, here is the program output:

DEBUG: lorem
DEBUG: ipsum
DEBUG: dolor
DEBUG: sit
DEBUG: amet
DEBUG: con
DEBUG: sec
DEBUG: euter
DEBUG: orci
Final: orci
Final: euter
Final: sec
Final: con
Final: amet
Final: sit
Final: dolor
Final: ipsum
Final: lorem
[浮城] 2025-01-18 08:57:03

您的主要问题是 line 已分配且 size 为零。如果您打算让 getline 为该行分配空间,则 size 必须为零且 line 必须为 null。另外,您应该在循环结束时释放分配的内存。

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

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

//a function to add word to front of linked list
link *addWord(char *word, link *head){
    link *temp1 = malloc(sizeof(link));

    //add string word to linked list
    temp1->word = strdup(word);
    temp1->next = head;
    return temp1;
}

int main(){
    FILE *fO; 
    fO = fopen("paragraph.data", "r");
    int size = 0;
    int len = 0;
    char *line;

    //loop through the file
    while(getline(&line, &size, fO) != EOF){
        char *word = strtok(line, " \n");

// addWord(词,头);
printf("单词:%s\n", word);

        while(word) {
            word = strtok(NULL, " \n");
            printf("the word: %s\n", word);

// addWord(词,头);
}
免费(线路);
}
}

Your main issue is that line is allocated and size is zero. If you intend to let getline allocate space for the line, then size must be zero AND line must be null. Also, you should free the allocated memory at the end of the loop.

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

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

//a function to add word to front of linked list
link *addWord(char *word, link *head){
    link *temp1 = malloc(sizeof(link));

    //add string word to linked list
    temp1->word = strdup(word);
    temp1->next = head;
    return temp1;
}

int main(){
    FILE *fO; 
    fO = fopen("paragraph.data", "r");
    int size = 0;
    int len = 0;
    char *line;

    //loop through the file
    while(getline(&line, &size, fO) != EOF){
        char *word = strtok(line, " \n");

// addWord(word,head);
printf("the word: %s\n", word);

        while(word) {
            word = strtok(NULL, " \n");
            printf("the word: %s\n", word);

// addWord(word,head);
}
free(line);
}
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文