从文件中的动态结构阅读 [英] Reading from file to dynamic struct

查看:93
本文介绍了从文件中的动态结构阅读的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一个文件,一行一行地读。每行有3个参数保证。首先是2名和姓,三是年龄。
我想打一个链表,其中,重$ P $每个节点psents在文件中的人(线)。
我不知道名字的大小,所以我把它的动态。我也不知道该文件中的行数,所以我想这是动态的了。

I would like to read from a file, line by line. Each line has 3 arguments guaranteed. First 2 are first and last name and third is age. I want to make a linked list, in which, each node represents a person (line) in the file. I don't know the size of the names so I made it dynamic. I also don't know the number of lines in the file, so I would like that to be dynamic too.

我的方法是使用的fscanf,但我不知道需要多少内存来阅读它之前分配。
该功能convertToList应该得到我们想要读取的文件的文件路径,将其转换为一个链表,然后返回头节点。 (开放的改进)

My approach was to use fscanf, but then I wouldn't know how much memory needs to be allocated prior to reading it. The function convertToList is supposed to receive a file path of the file we wanna read, convert it to a linked list, then return the head node. (Open to improvements)

看看我的code和看到我卡住了:

Check out my code and see where I got stuck:

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

typedef enum
{
    FALSE,
    TRUE 
}bool;

struct Node{
    char firstName[50];
    char lastName[50];
    int age;
    struct Node *next;
};

typedef struct {
    struct Node *head;
}LinkedList;


struct Node * convertToList(char *inputFilePath);

int main(int argc, char* argv[]) {

    if(argc != 4) {
        printf("Invalid arguments.\n");
        exit(0);
    }
    if (strlen(argv[3])!=1) {
        printf("Invalid sorting type.\n");
        exit(0);
    }

    char *inputFilePath = (char*) malloc(sizeof(char*) * strlen(argv[1]) +1);
    memcpy(inputFilePath, argv[1], strlen(argv[1]));
    char *outputFilePath = (char*) malloc(sizeof(char*) * strlen(argv[2]) +1);
    memcpy(outputFilePath, argv[2], strlen(argv[2]) +1);
    char *sortType = argv[3];

    //LinkedList* inputList = (LinkedList*)malloc(sizeof(struct Node));

    struct Node* head = malloc(sizeof(struct Node));

    head = convertToList(inputFilePath);
    printf("\n%s %s %d\n", head->firstName, head->lastName, head->age);
//              printf("\nsaaap\n");

    getchar();


}

struct Node * convertToList(char *inputFilePath) {
FILE* ifp;
ifp = fopen(inputFilePath, "r");
if (!ifp) { perror("fopen"); exit(0); }
struct Node *head = NULL;
struct Node *prev = NULL;
bool isHead = TRUE;
while(!feof(ifp))   {
    struct Node *tmp = (struct Node*)malloc(sizeof(struct Node));
    if (prev != NULL)
        prev->next = tmp;


    if (head==NULL) 
        head = tmp;

    fscanf(ifp, "%s %s %d\n", tmp->firstName, tmp->lastName, &tmp->age);
    prev = tmp;

    //Need to link to next node as well

}

fclose(ifp);
return head;

}

我知道的fscanf是错误的,但我不知道如何解决它。
另外,我怎么回的根源?我的做法会工作吗?
最后,如​​何我可以设置列表中的下一个节点?我看不出它与当前while循环发生。

I know that the fscanf is wrong, but I'm not sure how to fix it. Also, how do I return the root? Is my approach gonna work? And lastly, how do can I set the next node in the list? I don't see it happening with the current while loop.

感谢。

推荐答案

如果您需要将节点联系起来,这是你如何能做到它,并使用动态存储,在这里你走了,我没想到这非常,但它就可以了。

If you need to link the nodes this is how you can do it and use dynamic storage, here you go, I didn't think this very much but it is Ok.

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

struct Node
{
    char *firstName;
    char *lastName;
    int   age;
    struct Node *next;
};

struct Node *convertToList(const char *const inputFilePath);
void freeList(struct Node *);

int main(int argc, char* argv[])
{
    struct Node *head;

    if (argc != 2)
    {
        printf("Invalid arguments.\n");
        return 1;
    }

    head = convertToList(argv[1]);
    if (head != NULL)
    {
        struct Node *current;

        current = head;
        while (current != NULL)
        {
            fprintf(stderr, "%s %s %d\n", current->firstName, current->lastName, current->age);
            current = current->next;
        }
        /* do manupulations with the list, example above, print the values */
        freeList(head);
    }
    return 0;
}

void freeList(struct Node *node)
{
    struct Node *current;

    current = node;
    while (current != NULL)
    {
        struct Node *next;

        next = current->next;
        if (current->firstName != NULL)
            free(current->firstName);
        if (current->lastName != NULL)
            free(current->lastName);
        free(current);

        current = next;
    }

}

size_t appendChar(char **buffer, char character, size_t length)
{
    char *temporary;
    if (buffer == NULL)
        return length;
    temporary = realloc(*buffer, 1 + length);
    if (temporary == NULL)
        return length;
    temporary[length] = character;
    *buffer           = temporary;

    return 1 + length;
}

struct Node *parseFileLine(char *line)
{
    char        *word;
    struct Node *node;
    char        *endptr;

    if (line == NULL)
        return NULL;

    node = malloc(sizeof(struct Node));
    if (node == NULL)
        return NULL;

    node->firstName = NULL;
    node->lastName  = NULL;
    node->age       = -1; // an invalid value;
    node->next      = NULL;

    word = strtok(line, " ");
    if (word == NULL)
        return node;
    node->firstName = strdup(word);

    word = strtok(NULL, " ");
    if (word == NULL)
        return node;
    node->lastName = strdup(word);

    word = strtok(NULL, " ");
    if (word == NULL)
        return node;

    node->age = strtol(word, &endptr, 10);
    if (*endptr != '\0')
        node->age = -1;

    return node;
}

struct Node *getNode(FILE *file)
{
    char  *line;
    int    character;
    size_t length;

    line   = NULL;
    length = 0;
    while ((character = fgetc(file)) != EOF)
    {
        if (((char)character == '\n') && (line != NULL))
        {
            struct Node *node;

            length = appendChar(&line, '\0', length);
            node   = parseFileLine(line);
            free(line);

            return node;
        }
        length = appendChar(&line, (char)character, length);
    }

    if (line != NULL)
        free(line);

    return NULL;
}

struct Node *convertToList(const char *const inputFilePath)
{
    FILE        *ifp;
    struct Node *head;
    struct Node *current;
    struct Node *last;

    ifp = fopen(inputFilePath, "r");
    if (ifp == NULL)
    {
        perror("fopen");
        return NULL;
    }

    head = NULL;
    last = NULL;
    while ((current = getNode(ifp)) != NULL)
    {
        if (current == NULL)
            return head;
        if (head == NULL)
            head = current;
        if (last != NULL)
            last->next = current;
        last = current;
    }
    fclose(ifp);

    return head;
}

在这里,你还可以打印节点来查看数据是正确那里。

Here you can also print the nodes to see that the data is correctly there.

我想你不明白是什么的malloc 是,你不知道很多关于三分球也是如此,在你的的fscanf 您在的firstName 的lastName 存储数据,而无需为它分配内存,他们甚至没有初始化,你会得到一个分段错误。

I think you don't understand what malloc is for and you don't know much about pointers too, in your fscanf you are storing data in firstName and lastName without allocating memory for it, they are not even initialized so you would get a segmentation fault.

这篇关于从文件中的动态结构阅读的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆