简体   繁体   中英

Read linked list from file with a special characters #

I have a problem with an exercise. I should read the written file, which contains two struct one another, the second struct that is the product should stop reading when reading the # character from the file, and then start reading before the struct and then stock the product. Can you help me?

I can not read from the struct file, and then make it stop to the character #. I think I need two while where the first law the elements of struct magazine, and the second law of those struct product and stop at the character #.

Is there anyone who could write code like this?

The file with each item on a separate line, only the line of the struct product is on the same line:

(Cod_p name quantity)

the whole is only separated to a space.

the file is organized as follows:

ENG0002
high street,8
London
England
SCG8888 Shorts 200
FFSF888 shirt 200
#
TRA456456
Park road,88
London
England
ASDASD000 shorts 100
ADWC000 shirt 1000
YUAYO shoes 122
#


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

struct magazine {
    char cod_m[30];
    char adress[30];
    char city[30];
    char nation[30];
    struct product* p;
    struct magazine* next;
    ``
};

struct product {
    char cod_p[10];
    char name[20];
    int quantity;
    struct product* next;
};

void read_st(struct magazzino* m);

int main() {
    struct magazzino* mag;
    read_st(mag);
}

void read_st(struct magazzino* m) {
    FILE* fp;
    fp = fopen("magazzino.txt", "r");

    while (!feof(fp)) {
        struct magazzino* m = (struct magazzino*)malloc(sizeof(struct magazzino));
        fscanf(fp, "%s\n%s\n%s\n%s\n", &m->cod_m, &m->adress, &m->city, &m->nation);
        m->next;
        printf("%s\n%s\n%s\n%s\n", &m->cod_m, &m->adress, &m->city, &m->nation);
    }
}

struct prodotto* LeggiProdotto(char filename) {
    FILE* fp = fopen("magazzino.txt", "r");
    while (!feof(fp)) {
        struct prodotto* p = (struct prodotto*)malloc(sizeof(struct prodotto));
    }
}

This is quite a difficult parsing problem, and fscanf() isn't sophisticated enough for it, because fscanf() treats whitespace as a separator, and so can't read strings with embedded spaces. Additionally, if you don't get what you want with fscanf , it's difficult to tell what you did get.

I would use fgets() instead. Here is how I would read the list of magazzino items using fgets() :

void rtrim(char *str)
{
    str[strcspn(str, "\r\n")] = '\0';
}

void read_magazzino(struct magazzino **m)
{
    FILE* fp;
    int finished = 0;
    char buf[30];
    fp = fopen("magazzino.txt", "r");

    while (!finished) {
        char *read = fgets(buf, 30, fp);
        if (read != NULL && buf[0] != '\0') {
            *m = malloc(sizeof(struct magazzino));    
            strcpy((*m)->cod_m, buf);
            rtrim((*m)->cod_m);
            fgets((*m)->adress, 30, fp);
            rtrim((*m)->adress);
            fgets((*m)->city, 30, fp);
            rtrim((*m)->city);
            fgets((*m)->nation, 30, fp);
            rtrim((*m)->nation);
            read_prodotto(fp, &(*m)->p);
            m = &(*m)->next;
        }
        else {
            *m = NULL;
            finished = 1;
        }
    }
    fclose (fp);
}

Notice that fgets() leaves the carriage return on the end of the string, so you need to trim it off. Notice also that I passed the struct magazzino to this function as a pointer to a pointer -- struct magazzino ** . Just sending it as a pointer would mean that the variable for it in main() would be unaffected by creating the list. Here's how I called it from main() , passing the variable's address to make it a pointer to a pointer:

struct magazzino *mag;
read_magazzino(&mag);

To read the products, I would continue to use fgets() . We can check for the # character in the buffer when we read each line. To extract the product's fields from the line, I used sscanf() , which is similar to fscanf() in that it takes a format string. Assuming the product names don't have any spaces in them, this should be fine.

void read_prodotto(FILE *fp, struct prodotto **p)
{
    char buf[60];
    int finished = 0;
    while (!finished) {
        fgets(buf, 60, fp);
        if (buf[0] != '#') {
            *p = malloc(sizeof(struct prodotto));
            sscanf(buf, "%s%s%d", (*p)->cod_p, (*p)->name, &(*p)->quantity);
            p = &(*p)->next;
        }
        else {
            *p = NULL;
            finished = 1;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM