Avatar billede alfred Nybegynder
20. oktober 1999 - 17:15 Der er 12 kommentarer og
1 løsning

filhåndtering

Hvordan læser jeg en bestemt linie i en fil der hedder "13.txt"?
Avatar billede alfred Nybegynder
20. oktober 1999 - 17:17 #1
Det skal helst være i c....
Avatar billede bjarke Nybegynder
21. oktober 1999 - 07:46 #2
Det kommer an på hvordan filen er opbygget, men ellers betyder tegnet '\r' (så vidt jeg husker) linieskift. Så du tæller bare hvor mange af dem du har passeret og indlæser så linien. '\r'=13 (vistnok).

Nå nej, det behøver du vist ikke!

// Hvis du skal åbne linie 13:
int linieNr = 13;
char linie[MAX]; // NB: Sørg for at MAX er mindst lige så stor, som den længste linie i filen!!!!
// Åben filpointer til filen her hvor denne kommentar står
fopen("13.txt",filpointer);
for(i=0; i<linieNr; i++)
  fgets(linie,filpointer);
fclose(filpointer);


Det skal sandsynligvis rettes lidt til og syntaksen er nok heller ikke helt rigtigt (det er længe siden, at jeg har arbejdet med c), men princippet skulle være der og den 13. linie stå i strengen linie, når ovenstående er afsluttet.

Ellers skriv igen hvis ikke du kan få det til at virke.
Avatar billede bjarke Nybegynder
21. oktober 1999 - 07:48 #3
// Åben filpointer...
skal ikke være der, og filpointer skal selvfølgelig erklæres:
FILE* filpointer;
Avatar billede soepro Nybegynder
21. oktober 1999 - 10:48 #4
Hvis filen derimod har fast længde på hver linie, kan du gøre sådan her:

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

typedef    struct
{
  char    Navn[30];
  char    Adresse[25];
  char    PostNrBy[25];
}          linieDef;
const int  linielaengde = sizeof(linieDef);

int main(int argc, char *argv[])
{
  FILE    *filpointer;
  linieDef linie;
  char    *filnavn    = "\\util\\13.txt";
  char    linieLAEST = 0;
  int      linienr    = 3;

  if (argc > 1)
  {
    if (argc > 2)
    {
      filnavn = argv[1];
      linienr = atoi(argv[2]);
    }
    else
      linienr = atoi(argv[1]);
  };

  filpointer = fopen(filnavn, "rb");
  if (filpointer != NULL)
  {
    if (fseek(filpointer, (linienr - 1) * linielaengde, SEEK_SET) == 0
    &&  fread(&linie, sizeof(linie), 1, filpointer)              == 1)
      linieLAEST = 1;
    fclose(filpointer);
  };

  if (linieLAEST)
    cprintf("Linie %d er læst i filen \'%s\' og indeholder:\r\n"
            "%.*s\r\n" /* Til Navn */
            "%.*s\r\n" /* Til Adresse */
            "%.*s\r\n", /* Til postnr. & by */
            linienr, filnavn,
            sizeof(linie.Navn)-1, linie.Navn,
            sizeof(linie.Adresse)-1, linie.Adresse,
            sizeof(linie.PostNrBy)-1, linie.PostNrBy);
  else
    cprintf("Linie %d i filen \'%s\' kunne ikke læses.\r\n",
            linienr, filnavn);

  return 0;
}

Tricket med '%.*s' i do cprintf sikrer at der kun udskrives maximalt det antal tegn som feltet KAN indeholde. (Herved undgås ballade, hvis det sidste tegn i en af stregen ikke er '\x0'.)
Avatar billede alfred Nybegynder
21. oktober 1999 - 10:55 #5
Soepro>>Filen har ikke en fast længde, men gør det noget? Jeg kan vel godt bruge din metode alligevel?
Avatar billede bjarke Nybegynder
21. oktober 1999 - 10:57 #6
Hvorfor skulle det ikke være '\x0' ?
Avatar billede bjarke Nybegynder
21. oktober 1999 - 11:02 #7
alfred >> nej, for soepro bruger netop linielængden i algoritmen:
  if (fseek(filpointer, (linienr - 1) * linielaengde, SEEK_SET) == 0

Her springer han straks til liniens begyndelse ved at regne ud i bytes hvor det er!
Avatar billede alfred Nybegynder
21. oktober 1999 - 11:04 #8
Jeg har ikke '\x0' i enden af mine linier - det skal jeg måske have?
Avatar billede bjarke Nybegynder
21. oktober 1999 - 11:10 #9
Næh, det må være variablen soepro taler om, for der sluttes strenge altid med '\x0' (=0). Linier i en normal tekstfil slutter (som jeg startede med at skrive) med '\r' (=13).
Avatar billede soepro Nybegynder
21. oktober 1999 - 11:16 #10
Du kan IKKE bruge min metode, hvis filens linier IKKE har fast længde - så er bjarke's eksempel den rigtige måde.

Eneste anden måde, er at indlæses større blokke vha. min metode, og så manuelt gennemsøge disse blokke efter den søgte linie. Ved at øge længden på det der læses til f.eks. 32 KB vil funktionen performe bedre, da en alm. harddisk normalt læser 32 KB ad gangen. Under Win95 læses altid i blokke på 32 KB, og da windows selv laver "cache", så er genvinsten ved at læse 32 KB ad gangen umærkbar.
Avatar billede bjarke Nybegynder
21. oktober 1999 - 11:17 #11
Tak, men lige en ting: Måske er det alligevel ikke '\r' men '\n' (=14). Jeg er ikke sikker.

Hvis det er en binær fil, som soepro skriver om, så mener jeg at kunne huske, at både '\r' og '\n' afslutter linien.
Avatar billede kampfeldt Nybegynder
27. oktober 1999 - 17:57 #12
\n er en escape kode for linieskift :)
Avatar billede bjarke Nybegynder
27. oktober 1999 - 18:09 #13
I know.

Jeg skriver lige lidt af fra en bog:

Ved brug af en tekststrøm er der normalt en entydig overensstemmelse mellem de tegn, der sendes fra programmets variabler og dem, der modtages af den ydre enhed. Der er to undtagelser fra denne regel: Tegnene for ny linie '\n' og for filslutmærket (tegn nr. 26 i tegntabellen) får en speciel behandling. Hvis tegnet '\n' sendes fra programmet, vil den ydre enhed modtage to tegn: '\r' (carriage return) og '\n' (line feed), der har henholdsvis nr. 13 og 10 i tegntabellen. Omvendt til tegnparret '\r', '\n' sendt fra en ydre enhed i programmet blive modtaget som ét tegn: '\n'. Dette spiller en vigtig rolle, når vi har at gøre med en DOS tekstfil, hvor vi skal have begge tegnene '\n' og '\r' for at gå til første position på næste linie.

det var det jeg ikke helt kunne huske, da jeg skrev ovenstående :-)
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