Avatar billede mieritz Nybegynder
23. marts 2004 - 14:13 Der er 15 kommentarer og
1 løsning

Læse og skrive til fil

Vi har en fil der er opbygget som følgende.
idcode,user_name,zone1,zone2,pris,saldo

idcode er char[17]
user_name er char[80]
zone1 og zone 2 er int
pris og saldo er float

Værdierne i filen er sepereret med (,) i filen og der er er mange linjer i den.

Det der skal ske er at når programmet starter læser vi fra filen. Her skal der hentes de 10 idcoder fra de første 10 linjer i filen, som er er defineret i forvejen. Vores problem lige i øjeblikket er at den står og læser samme linje i filen 10 gange.

Når vi skal skrive til filen vil vi gerne skrive ind i den som angivet i starten, men hvordan skriver man ind i filen så den bliver kommasepereret og hvordan læses den så når man skal læse en hel linje.
Avatar billede arne_v Ekspert
23. marts 2004 - 14:31 #1
Hvis I kun åbner filen en gang og i læser linier, så bør I også bevæge jer
frem i filen.

Skrivning/C:

fprintf("%s,%s,%d,%d,%f,%f\n",idcode,user_name,zone1,zone2,pris,saldo);

Skrivning/C++:

fout << idcode << "," << user_name << "," << zone1 << "," << zone2 << "," << pris << "," << saldo << endl;

Ved lædning bliver I nødt til at læse en hel linie og så parse den op i
felter og så konvertere tal felterne til int og double.
Avatar billede arne_v Ekspert
23. marts 2004 - 14:33 #2
Læse hel linie/C:

fgets(buf,sizeof(buf),fp);

Læse hel linie/C++:

fin.getline(buf,sizeof(buf));
Avatar billede arne_v Ekspert
23. marts 2004 - 14:34 #3
Og jeg glemte første argument i:

fprintf(fp,"%s,%s,%d,%d,%f,%f\n",idcode,user_name,zone1,zone2,pris,saldo);

sorry
Avatar billede mieritz Nybegynder
23. marts 2004 - 16:38 #4
vi skriver i c++, men hvordan åbnes filen og hvordan bevæger vi os frem i filen og hvordan fortæller man at den skal skifte linje når den har læst første linje.
Avatar billede arne_v Ekspert
23. marts 2004 - 16:53 #5
noget a la:

ifstream fin("filnavn.ext");
while(!fin.eof())
{
  char buf[1000];
  fin.getline(buf,sizeof(buf));
  // process buf
}
Avatar billede mieritz Nybegynder
23. marts 2004 - 17:39 #6
hvordan ved den at den skal skifte linje gør den det af sig selv
Avatar billede arne_v Ekspert
23. marts 2004 - 18:00 #7
getline læser en  linie og positionerer sig til at læse næste linie.
Avatar billede mieritz Nybegynder
23. marts 2004 - 18:18 #8
jeg forstår ikke helt hvorfor du opretter char buf[1000]. Hvad skal den bruges til og hvad er det for nogle argumenter du giver til getline
Avatar billede arne_v Ekspert
23. marts 2004 - 18:44 #9
buf er en buffer til at indeholde linien.

getline får at vid ehvilken buffer den skal læse til og hvor meget plads der er
Avatar billede bertelbrander Novice
23. marts 2004 - 23:05 #10
Man kunne bruge følgende til at læse (og skrive), det er ren C, men bør kunne bruges i C++:

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

typedef struct Whatever
{
public:
  char idcode[17];
  char user_name[80];
  int zone1;
  int zone2;
  float pris;
  float saldo;
}Whatever;

int main()
{
  Whatever whatever[10];
  int i, Num, NumScanned;

  FILE *f = fopen("myfile.dat", "rt");
  if(!f)
  {
    fprintf(stderr, "Failed to open file!\n");
    return EXIT_FAILURE;
  }
  memset(whatever, 0, sizeof(whatever));
  NumScanned = 6;
  for(i = 0; i < 10 && NumScanned == 6; i += NumScanned == 6 ? 1 : 0)
    NumScanned = fscanf(f,
                        "%[^,],%[^,],%d,%d,%f,%f\n",
                        whatever[i].idcode,
                        whatever[i].user_name,
                        &whatever[i].zone1,
                        &whatever[i].zone2,
                        &whatever[i].pris,
                        &whatever[i].saldo);
  Num = i;
  printf("Num Read: %d\n", Num);

  for(i = 0; i < Num; i++)
    printf("%s,%s,%d,%d,%f,%f\n",
          whatever[i].idcode,
          whatever[i].user_name,
          whatever[i].zone1,
          whatever[i].zone2,
          whatever[i].pris,
          whatever[i].saldo);
  fclose(f);
  return 0;
}
Avatar billede mieritz Nybegynder
24. marts 2004 - 09:23 #11
det ser megeet godt ud, men kunne du måske forklare mig hvad det er der sker ned gennem koden. Jeg forstår ikke helt det med NumScanned. Lægger du det du læser ind over i numscanned eller hvad sker der og hvorfor lige de argumenter i if løkken. Jeg prøver lige at omdefinere mit spørgsmål, men det er noget i den stil jeg skal bruge.
Min fil er som følger.
idcode,user_name,zone1,zone2,pris,saldo
idcode,user_name,zone1,zone2,pris,saldo
idcode,user_name,zone1,zone2,pris,saldo
idcode,user_name,zone1,zone2,pris,saldo
.....
sådan fortsætter den derned ad. Jeg skal have læst disse værdier ind i mit program linke for linje og de skal så placeres forskellige steder på en grænseflade senere, men først skal de gemmes i værdier i programmet så jeg har adgang til dem for hver bruger(1 bruger er en linje i filen). Dvs. at der skal læses fra filen når programmet starter, derefter skal der være adgang til dataerne i programmet så de kan redigeres og til sidst så skrives tilbage til filen. Det jeg har brugt nu er ifstream, men jeg kan godt få læst det ind, men har ingen ide om hvordan jeg så får fat i værdierne i fil objektet.
Avatar billede mieritz Nybegynder
24. marts 2004 - 10:23 #12
jeg tror jeg er ved at forstå hvad der står, så jeg prøver lige at forklare det så kan du jo lige skrive om jeg er helt ved siden af. Du starter med at lave en struct. Jeg har det godt nok liggende i en klasse, men det gør ingen forskel. Derefter opretter du et filobjekt f som så bliver testet for om det er åbent. Så er der memset. Så vidt jeg kan forstå skulle den se på mit array af bugere(whatever), sætte en char(0) og finde størrelsen af denne. så kommer for løkken og der forstår jeg ikke helt de argumenter du bruger. Jeg kan godt forstå hvad der står men ikke hvorfor det skal stå sådan og jeg kan heller ikke forstå hvorfor NumScanned skal være lig med det der bliver læst ind.
Den første printf skulle så vidt jeg forstå tælle hvor mange linjer der er scannet i filen. Og til sidst skal der så skrives til filen, men skriver den i starten af filen eller skriver den i bunden af filen det vil jeg gerne vide, for den skal jo skrive i bunden.
Jeg har også lige et andet spørgsmål. Efterhånden som programmet kører vil der kommer flere og flere linjer i filen. Det skal derfor være muligt at søge efter den nyeste linje i filen for den pågældende bruger, men hvordan skal vi gribe det an.
Avatar billede bertelbrander Novice
24. marts 2004 - 20:13 #13
fscanf returnerer det at antal felter den har læst, da den i dette tilfælde skal læse en hel linie af gangen skal den scanne 6 felter. Hvis ikke den har gjort det er der opstået en fejl, eller den har nået enden på filen.

I format argumentet til fscanf betyder %[^,] at den skal læse en streng indtil den når til et komma. %d betyder int og %f betyder float.

fscanf gemmer det den har læst i whatever[i].idcode osv.

memset sætter hele strukturen til 0, og er bør ikke være nødvendig.

Num bliver sat til at være det antal linier/brugere der er læst.

Hvis du vil tilføje til enden på en fil bruger du:

FILE *f = fopen("myfile.dat", "at");

til at åbne filen, og du bruger:

FILE *f = fopen("myfile.dat", "wt");

til at åbne hvis du vil overskrive det hele.

Hvis du læser og gemmer alle brugeres data i starten af starten af programmet er det vel lettest overskrive det der står i filen, og gemme alle brugere når du afslutter programmet, derved slipper du for at have brugere i filen mere end en gang.
Avatar billede mieritz Nybegynder
25. marts 2004 - 10:34 #14
jeg forstår ikke hvorfor du gør det her

for(i = 0; i < 10 && NumScanned == 6; i += NumScanned == 6 ? 1 : 0)
    NumScanned = fscanf(f,
                        "%[^,],%[^,],%d,%d,%f,%f\n",
                        whatever[i].idcode,
                        whatever[i].user_name,
                        &whatever[i].zone1,
                        &whatever[i].zone2,
                        &whatever[i].pris,
                        &whatever[i].saldo);
hvorfor sætte numscanned=fscanf, det kan jeg ikke rigtig se og hvorfor lige disse argument i løkken
Avatar billede bertelbrander Novice
25. marts 2004 - 19:52 #15
Jeg er ikke sikker på at jeg forstår hvad det er du ikke forstår; for mig at se er ovenstående en lige-ud-af-landevejen for-loop, der gør følgende:

1: NumScanned sættes til 6
2: i sættes til 0
3: det checkes om i er mindre end 10 og om NumScanned er 6, hvis ikke afsluttes.
4: Læs en linie, dvs 6 felter fra filen, NumScanned sættes til antallet af felter der kunne scannes. Hvis der er opstået en fejl vil der være scannet mindre end 6 felter. Resultatet bliver gemt i whatever[i].
5: Hvis der blev scannet 6 felter tælles i én op
6: Gå til 3

Derved vil der blive læst fra filen så længe der er flere linier i filen og der er læst mindre end 10 linier, og i vil ved afslutning af løkken være antallet af linier der kunne læses.

Mere hardcore programmører vil måske skrive ovenstående som:

for(i = 0;
    i < 10 && fscanf(f,
                    "%[^,],%[^,],%d,%d,%f,%f\n",
                    whatever[i].idcode,
                    whatever[i].user_name,
                    &whatever[i].zone1,
                    &whatever[i].zone2,
                    &whatever[i].pris,
                    &whatever[i].saldo) == 6;
    i++)
{
}
Avatar billede arne_v Ekspert
12. april 2004 - 20:52 #16
Lukke tid ?
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