Avatar billede rene_p Nybegynder
08. maj 2003 - 13:24 Der er 5 kommentarer og
1 løsning

Kædet liste af strukturer.

Jeg er ved at skrive et program i C der skal læse en tekstfil og overføre filens indhold til en strukturvariabel. Tekstfilen ser sådan ud:

Id    Dato         Antal timer

1000    29/4-2003    8,5
1000    30/4-2003    7,5
1001    29/4-2003      7,5
1001    30/4-2003    8.5

Problemet består i at linke funktionerne hent_id, hent_dato og hent_timer i funktionen hent_timepulje() således at parameterne ligges i structurvariablen struct timepulje, og at jeg kan bruge structurvariablen til at udregne løn i en funktion. Nedenunder ses den ufærdige kode. 

Håber der er nogle som kan hjælpe med løse problemet, og hjælpe mig på sporet igen!

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

int hent_timepulje();
int hent_id(char, char, int);
int hent_dato(char, char, int);
int hent_timer(char, char, int);

struct timepulje
{
  int id;
  char dato[20];
  float timer;
  struct timepulje *pnaeste;
};

struct timepulje *pfoerste, *psidste, *pny;

int hent_timepulje()
{
  FILE *fptr;
  char ch;
  char sLinie[81];
  char id[81];
  char i[81];
  int j = 0;

  if((fptr = fopen("c:\\timepul.txt", "r")) == NULL)
  {
    printf("\nFilen tekstfil.txt kan ikke åbnes. ");
    exit(1);
  }

  printf("Filen har indholdet: \n\n");

  while((fgets(sLinie, 81, fptr) != NULL))
  {
    pny = malloc(sizeof(struct timepulje));

    if(pfoerste == NULL)
    pfoerste = psidste = pny;
   
    else
    {
      psidste->pnaeste = pny;
      psidste = pny;
    }

    i = hent_id(sLinie, id, i);
    pny->id = atoi(id);

    i = hent_dato(sLinie, dato, i);


    i = hent_timer(sLinie, timer, i);
  }
}

int hent_id (char Linie[], char id[], int i)
{
  char ch;
  int j = 0;

  while ((ch = sLinie[i]) == ' ' && sLinie[i] == '\n')
  {
  i++;
  }

  while ((ch = sLinie[i]) != ' ' && sLinie[i] != '\n')
  {
    id[j] = ch;
    i++;
    j++;
  }
  id[j] = '\0';
  i++;

  fclose(fptr);
  return id;
}

int hent_dato (char Linie[], char dato[], int i)
{
  char ch;
  int j = 0;

  while ((ch = sLinie[i]) == ' ' && sLinie[i] == '\n')
  {
    i++;
  }

  while ((ch = sLinie[i]) != ' ' && sLinie[i] != '\n')
  {
    dato[j] = ch;
    i++;
    j++;
  }

  dato[j] = '\0';
  i++;
  fclose(fptr);
  return dato;
}

int hent_timer (char Linie[], char timer[], int i)
{
  char ch;
  int j = 0;

  while ((ch = sLinie[i]) == ' ' && sLinie[i] == '\n')
  {
    i++;
  }

  while ((ch = sLinie[i]) != ' ' && sLinie[i] != '\n')
  {
    timer[j] = ch;
    i++;
    j++;
  }
  timer[j] = '\0';
  i++;

  fclose(fptr);
  return timer;
}

void main(void)
{
  hent_timepulje();
}
Avatar billede chries Nybegynder
08. maj 2003 - 13:32 #1
lige en ting, alle
while ((ch = sLinie[i]) == ' ' && sLinie[i] == '\n')

vil aldrig kunne være sandt! den kan ikke både være space og "enter" på en gang.
Avatar billede arne_v Ekspert
08. maj 2003 - 13:36 #2
Første problem må være at få parset dato og timer.

Timer er nem hvis der bruges konsekvent "." og ikke ",".

double v;
sscanf(id,"%d",&v);
Avatar billede arne_v Ekspert
08. maj 2003 - 13:37 #3
Og dato har du valgte at have som char array. D.v.s. at den kan du
bare flytte over med strcpy.
Avatar billede arne_v Ekspert
08. maj 2003 - 13:40 #4
char dato[21];
  double timer;

  ...

    i = hent_dato(sLinie, dato, i);
    strcpy(pny->dato, dato);

    i = hent_timer(sLinie, timer, i);
    sscanf(timer,"%d",&pny->timer);
Avatar billede arne_v Ekspert
08. maj 2003 - 13:40 #5
Eller har jeg misforstået noget ?
Avatar billede segmose Nybegynder
10. maj 2003 - 16:14 #6
I tilføjelse af chriez kommentar så får du heller ikke checket at det ikke er en tom linie.

hver eneste hent_ funktion er fejlbehæftet da den ikke checker for buffer overflow.
Erstat selv assert med passende fejlmeldinger.

main skal som minimum defineres som

int main() {

Løsning:
i hent_timepulje ud skift alle hent_xxx code med følgende.

char safe[sizeof(sLine)]; /* sikker buffer til dato, evt. i toppen af hent_timepulje */

assert(pny); /* du har ikke sikkeret at du overhovedet har fået en pny */
if (3 != sscanf(sLine, "%d %s %f", &pny->id, safe, &pny->timer)) {
  /* evt. yderligere check om vi ikke bare har en tom linie */
  printf("det gik ikke så godt lad os straks falde død om\n";
  exit(EXIT_FAILURE);
}
assert(strlen(safe)<20); /* ærgeligt at "%19s" ikke virker */
strcpy(pny->dato, safe);

Uløste problemer:
ved tom linie får du en tom record!!!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester