-1

I have a text documet which has the following data

$
osobny automobil
Ferrari
Autobazar Pestovatelska 4 Bratislava
68957
2012
udrziavane cervene dvojdverove
$
kamion
Renault magnum
AUTO Modranska 5 Senec
28000
2016
po havarii opraveny v dobrom stave
$
karavan
Kostitras
JANA, Vitanova 147
20250
2010
Voz na dovolenku

The structure looks like this:

typedef struct auta {  
    char kategoria [50];  
    char znacka [50];
    char predajca [100];
    int cena;
    int rok_vyroby;
    char stav_vozidla [200];
    struct auta *dalsi;
}AUTA;

And the thing my fucntion is supposed to do is read from this file a printf the number of entries. For example $ counts as one entry, so there would be three entries total. I have found it quite stupid to do this entry by entry with a different structure pointer as i am doing it now but the problem is i dont know how to make a sensible loop. What i have so far is how i read the first entry from the file.

AUTA *p=NULL;
p=(AUTA*)malloc(sizeof(AUTA));
    fgets(z[0],5,fr);
    fgets(p->kategoria,50,fr);
    fgets(p->znacka,50,fr);
    fgets(p->predajca,100,fr);
    fscanf(fr,"%d",&p->cena);
    fscanf(fr,"%d\n",&p->rok_vyroby);
    fgets(p->stav_vozidla,200,fr);

So the question would be how to load entries from the text file into the structure using a loop.

martinjan
  • 1
  • 1

1 Answers1

1

I'm not sure what language this is, but I'll assume that dalsi translates to next (if not, add a struct auta *next at the end of the structure). I'm also assuming you're a beginner so I'll go over some of what I'm doing below:

AUTA *pStart = NULL;   // keep track of start of list:
AUTA **pp = &pStart;   // set a pointer to the pointer of the active entry

while (!feof(fr)) {
    fgets(z[0],5,fr);
    if (feof(fr))
           break;
    if (strcmp(z[0],"$") != 0) 
           continue;   // non $ sign -- not start of record... ignore line
    // allocate record:
    *pp = malloc(AUTA*)malloc(sizeof(AUTA))
    if (*pp == NULL) {   // double check that malloc succeeded
        sprintf(stderr, "Out of memory\n"); 
        exit -1;
    }
    // read in record -- note pp points to the pointer to the 
    // record, so you want to access (*pp)-> ...
    fgets((*pp)->kategoria,50,fr);
    fgets((*pp)->znacka,50,fr);
    fgets((*pp)->predajca,100,fr);
    fscanf(fr,"%d",&(*pp)->cena);
    fscanf(fr,"%d\n",&(*pp)->rok_vyroby);
    fgets((*pp)->stav_vozidla,200,fr);
    (*pp)->dalsi = NULL;   // in case this is the last entry...
    pp = &(*pp)->dalsi;
}

This solution used double indirection (a pointer to a pointer), which is a bit to take in if you're new. I would suggest drawing a diagram if you're having trouble getting your head around it. Basically, we start with a pointer to the first record (pStart). pStart starts off as NULL. You then have a pointer to the pointer to the first entry (that is, pp points to pStart. You then start looping. If you find a $, you start reading. First, you allocate memory for a new record and set *pp to point to that (remember that pp pointed to pStart, ergo now *pp or pStart points to the new record. You then scan in that record. When you're done, you set pp to point to the next pointer (dalsi) of the current record, and loop. The second iteration of the loop will populate pStart->dalsi to point to the next record, so you end up with:

 pStart ------> (record1)     +---> (record2)    +---> (record3)
                  \ dalsi  ---+       \dalsi  ---+         \dalsi --> NULL
HardcoreHenry
  • 5,909
  • 2
  • 19
  • 44
  • Just make sure you understand it. This sounds like a homework assignment, and the last thing I want to do is to get you out of having to learn something :-) – HardcoreHenry Nov 29 '17 at 21:41
  • Concerning `while (!feof(fr)) {`, review [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – chux - Reinstate Monica Nov 29 '17 at 21:48
  • Certinaly `fgets(z[0],5,fr); if (strcmp(z,"$")...` is broken code. `z[0]` de-references the pointer. – chux - Reinstate Monica Nov 29 '17 at 21:50
  • Thanks @chux -- sorry, a bit hastily written. OP quoted the check against `z[0]`, not sure if they mean `&z[0]`, but I'll assume it's a pointer to an array of strings. For the `feof` issue, I created another test after trying to read the `$`. – HardcoreHenry Nov 30 '17 at 15:50
  • Checking `feof()` makes most sense _after_ receiving an end-of-file/error indication from `fgets()`. Rather than `fgets(....); ... if (feof(...)) done()`, use `if(fgets(...) == NULL) done();` – chux - Reinstate Monica Nov 30 '17 at 15:55