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.