Avatar billede testpilot_dk Nybegynder
17. juni 2005 - 16:53 Der er 18 kommentarer og
1 løsning

Find Forrige Linje i InputFil

Hej!

Jeg sidder og laver et projekt hvor der skal indlæses fra en fil, det går fint nok med.

fstream og getFile(Buffer, sizeof(Buffer)

mit spørgsmål er så, at når jeg har fundet ud af det jeg indlæste skal foresage en anden handling end den påbegyndte og jeg så ønsker at flytter min pointer tilbage i filen, hvordan gør jeg dette!

Jeg har forsøgt mig med en for loop som laver en "unget()" af den seneste karakter! det virker ikke rigtigt efter min menning, da jeg kan se at næste gang jeg læser linjen ind, så mangler der en masse "      "

void ReverseLine(fstream *inFile, char *Buffer)
{
  for(int i = 0; i < (int)strlen(Buffer); i++)
      inFile->unget();
  Buffer[0] = 0;
}
Avatar billede arne_v Ekspert
17. juni 2005 - 17:27 #1
det man normal gør i den situation er:

forrige linie = læs linie
while not eof {
    linie = læs linie
    hvis linie opfylder betingelserne {
        process forrige linie
    }
    forrige linie = linie
}
hvis linie opfylder betingelserne {
    process forrige linie
}
Avatar billede arne_v Ekspert
17. juni 2005 - 17:28 #2
ovenstående er pseudo kode - jeg kan godt lave et C++ eksempel hvis nødvendigt
Avatar billede testpilot_dk Nybegynder
17. juni 2005 - 18:27 #3
ja, tak! det ville være rart! for jeg har ikke nogen ide om hvordan jeg skal få den til at fungere ordentligt!
Avatar billede arne_v Ekspert
17. juni 2005 - 18:50 #4
her kommer et eksempel

vi har en input fil

a
b
c
*
e
f
*
g

vi skal indlæse den og udskrive alle linier undtagen dem med * og dem der er lige
før en linie med *

kode

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
  ifstream f("test.txt");
  string line,lastline;
  lastline = "*"; 
  while(f && !f.eof())
  {
      getline(f,line);
      if(line != "*" && lastline != "*")
      {
          cout << lastline << endl;
      }
      lastline = line;
  }
  if(lastline != "*")
  {
      cout << lastline << endl;
  }
  f.close();
  return 0;
}

og korrekt output

a
b
e
g
Avatar billede testpilot_dk Nybegynder
17. juni 2005 - 19:41 #5
okay! jeg har nok ikke udtrykt mig klart nok!

Jeg sender lige et stykke kode

  while(!inFile->eof())
  {
      if(first)
      {
        inFile->ignore(6);
          inFile->getline(Buffer, sizeof(Buffer));
      }

      int t = strcspn(Buffer, "0");
        if(strncmp(Buffer, "* START OF IMPORT", 17) == 0 || strncmp(Buffer, "* START OF EXPORT", 17) == 0 || GetInProcess())
        {
            if(first)
            {
                inFile->getline(Buffer, sizeof(Buffer));
                inFile->getline(Buffer, sizeof(Buffer));
            inFile->getline(Buffer, sizeof(Buffer));
            SetInProcess(true);
            }
            while(strncmp(Buffer, "* * *", 5) != 0)
            {
            if(GetInProcess())
            {
              inFile->ignore(6);
                  inFile->getline(Buffer, sizeof(Buffer));
            }
            else
              break;

            if(GetRG() && Buffer[strlen(Buffer)-2] == 'G' && Buffer[strlen(Buffer)-3] == 'R')
            {
              level = strcspn(Buffer, "0");
              ReverseLine(inFile, Buffer);
              break;
            }


......

Den linje jeg får læst ind, vil jeg gerne kunne læse ind igen næsten gang løkke når til GetLine(Buffer, sizeof(Buffer)), det er det som er mit problem
Avatar billede arne_v Ekspert
17. juni 2005 - 20:03 #6
og jeg mener stadigvæk at det korrekte approach er at have den forrige linie
gemt så man bare kan finde den frem igen i.s.f. at læse den ind igen
Avatar billede testpilot_dk Nybegynder
17. juni 2005 - 20:30 #7
det er selvføgelig en mulighed! 

Men hvordan vil den så fungerer når jeg ønsker at læse nogle flere linjer ind bagefter.

Hvor står pointeren så?
Avatar billede arne_v Ekspert
17. juni 2005 - 20:46 #8
så læser du ind og så står du der hvor du er kommet til
Avatar billede arne_v Ekspert
17. juni 2005 - 20:47 #9
jeg tror sagtens at vi kan flytte den pointer tilbage, men det er efter min
bedste overbevisning ikke den rigtige måde at gøre det på
Avatar billede testpilot_dk Nybegynder
17. juni 2005 - 20:56 #10
hvis vi tager dit eksempel! hvordan får jeg så skrevet c og f ud!
Avatar billede arne_v Ekspert
17. juni 2005 - 21:19 #11
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
  ifstream f("test.txt");
  string line,lastline;
  lastline = "*"; 
  while(f && !f.eof())
  {
      getline(f,line);
      if(lastline != "*")
      {
          if(line != "*")
          {
              cout << lastline << endl;
          }
          else
          {
              cout << "before * : " << lastline << endl;
          }
      }
     
      lastline = line;
  }
  if(lastline != "*")
  {
      cout << lastline << endl;
  }
  f.close();
  return 0;
}

giver

a
b
before * : c
e
before * : f
g
Avatar billede testpilot_dk Nybegynder
17. juni 2005 - 21:25 #12
Okay!

Jeg forsøger mig med det, men jeg får først mulighed for at teste det imorgen!

Mine funktioner er recursive og jeg får muligvis brug for at hente * ud i et andet lag!

Tror du det er muligt på denne måde ???
Avatar billede arne_v Ekspert
17. juni 2005 - 21:36 #13
line og lastline kunne jo gemmes globalt
Avatar billede testpilot_dk Nybegynder
17. juni 2005 - 23:25 #14
Jeg er bare ikke meget for at gemme variable globalt!
Avatar billede testpilot_dk Nybegynder
18. juni 2005 - 09:15 #15
Det virker ikke efter hensigten i mit projekt!

Jeg kan jo godt have kørt flere linjer ind, inden jeg skal bruge mine * ud igen, så skal jeg jo gemme op til 200 linjer, det er for besværligt!

Der må være en smart måde til at rykke sin pointer en linje tilbage i input filen
Avatar billede arne_v Ekspert
18. juni 2005 - 11:21 #16
det er faktisk ikke så besværligt at gemme mange linier i en cirkulær buffer

men jeg prøver lige at se om jeg kan lave et flyt eksempel
Avatar billede arne_v Ekspert
18. juni 2005 - 13:58 #17
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
  ifstream f("test.txt");
  string line;
  while(f && !f.eof())
  {
      getline(f,line);
      cout << line << endl;
      if(line == "*")
      {
          f.putback('\n');
          f.putback('*');
          getline(f,line);
          cout << "read again: " << line << endl;
      }
  }
  f.close();
  return 0;
}

giver:

a
b
c
*
read again: *
e
f
*
read again: *
g

altså putpack af '\n' og putback af alle de tegn som skal læses igen.
Avatar billede testpilot_dk Nybegynder
18. juni 2005 - 14:59 #18
Mange Takker!

Send du et svar og du får dine velfortjente points
Avatar billede arne_v Ekspert
18. juni 2005 - 15:02 #19
ok
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