Avatar billede teepee Nybegynder
07. april 2004 - 23:31 Der er 13 kommentarer og
2 løsninger

Rutine til konvertering af data i fil

Hej med jer,

Jeg har to filer. Fil1.txt (navnet inputafhængigt) som indeholder semikolon separerede data. Feltet efter det først semikolon (felt 2 om man vil) indeholder en værdi. Denne værdi skal slås op i felt2 i Fil2.txt (navnet inputafhængigt) For den linie hvor koden findes skal værdien i felt2 i Fil1.txt erstattes med værdien af felt1 fra Fil2.txt. Dette skal gøres for hver linie i Fil1.txt. Outputtet skal gemmes i en Fil1_ny.txt så Fil1.txt stadig er intakt.

Eks:

Fil1.txt
11111;22222;33333
11112;22223;12345

Fil2.txt
55;22222
56;22223
57;22134

Fil1_ny.txt
11111;55;33333
11112;56;12345


Opgaven er som sådan meget simpel, men da det skal køre som noget command/dos agtigt er jeg desværre stået af. Jeg har lidt ekstra lirr jeg gerne vil have i løsningen, men dertil vil jeg oprette et ekstra spm senere. I skulle jo gerne have nogle ordentlige point ud af opgaven. Kan I hjælpe?
Avatar billede arne_v Ekspert
07. april 2004 - 23:35 #1
Du vil med andre ord gerne lave en:
  SELECT fil1.kolonne1,fil2.kolonne1,fil1.kolonne3
  FROM fil1 JOIN fil2 ON fil1.kolonne2=fil2.kolonne2
?

To spørgsmål:
1)  hvorfor importerer du ikke i en database, joiner og eksporterer igen ?
2)  hvor store data mængder ?
Avatar billede bertelbrander Novice
08. april 2004 - 00:50 #2
Måske noget i stil med:

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>

using namespace std;

typedef map<int, int> MyMap;

int main(int argc, char *argv[])
{
  if(argc != 4)
  {
    cout << "usage: " << argv[0] << " file1 file2 outfile" << endl;
    return EXIT_FAILURE;
  }

  FILE *f = fopen(argv[2], "rt");
  if(!f)
  {
    cout << "Failed to open " << argv[2] << endl;
    return EXIT_FAILURE;
  }

  map <int, int> File2Map;
  char line[128];
  while(fgets(line, sizeof(line), f))
  {
    char *s = strtok(line, ";");
    int fv = strtol(s, 0, 10);
    s = strtok(0, "\n");
    int sv = strtol(s, 0, 10);
    File2Map.insert(make_pair(sv, fv));
  }
  fclose(f);

  f = fopen(argv[1], "rt");
  if(!f)
  {
    cout << "Failed to open " << argv[1] << endl;
    return EXIT_FAILURE;
  }
  FILE *out = fopen(argv[3], "wt");
  if(!f)
  {
    cout << "Failed to open " << argv[3] << endl;
    return EXIT_FAILURE;
  }

  while(fgets(line, sizeof(line), f))
  {
    char *fp = strtok(line, ";");
    char *mp = strtok(0, ";");
    char *lp = strtok(0, "\n");
    int v = strtol(mp, 0, 10);
    map<int, int>::iterator i = File2Map.find(v);
    if(i != File2Map.end())
    {
      fprintf(out, "%s;%d;%s\n", fp, i->second, lp);
    }
    else
      cout << "Failed to match: " << v << endl;
  }
  fclose(f);
  fclose(out);
}
Avatar billede teepee Nybegynder
08. april 2004 - 13:15 #3
arne_v => ville meget gerne, men dødelige brugere skal manuelt kunne gøre dette når det passer dem. Dertil vil jeg gerne undgå at der skal en database til.
bertelbrander => ser meget fornemt ud, vil se om jeg kan få det til at virke i aften, pft.
Avatar billede arne_v Ekspert
08. april 2004 - 13:27 #4
Jo men selv Access kan jo gøre det. En lille form med 3 felter til
filnavne og så en stor fed command button der fyrer lidt passende
komamndoer af.

Men iøvrigt ser Bertels løsning fortrinlig ud (forudsat at fil2 kan være
i memory - jævnfør det ene af mine spørgsmål).
Avatar billede teepee Nybegynder
08. april 2004 - 20:18 #5
Jeg tror at det måske kan dreje sig om et par tusinde rækker med kodepar til konvertering, absolut ikke mere. I alt en Mb's penge eller sådan.
Avatar billede arne_v Ekspert
08. april 2004 - 20:37 #6
Så er Bertels løsning lige det du skal bruge.
Avatar billede teepee Nybegynder
08. april 2004 - 20:39 #7
bertelbrander => SUPER!! Gider du at skrive et "svar" så jeg kan give dig 200 point ;-)
Kan du evt. lige fortælle mig hvorledes jeg gør den tredje parameter (outputfilen) til default fil1.konv, altså bare tilføjer ".konv" til fil1 navnet hvis 3. parameter ikke er specificeret?
Avatar billede arne_v Ekspert
08. april 2004 - 21:07 #8
if(argc < 3)
  {
    cout << "usage: " << argv[0] << " file1 file2 [outfile]" << endl;
    return EXIT_FAILURE;
  }
...
char fnm[256];
if(argc < 4)
{
  strcpy(fnm, argv[1]);
  char *p = strrchr(fnm,'.');
  strcpy(p,".conv");
}
else
{
  strcpy(fnm, argv[3]);
}
FILE *out = fopen(fnm, "wt");
Avatar billede arne_v Ekspert
08. april 2004 - 21:08 #9
Den sidst

if(!f)

skal nok være

if(!out)
Avatar billede bertelbrander Novice
09. april 2004 - 00:16 #10
Arnes rettelser ser rigtige ud.

Jeg forsøger at undgå point, men Arne bør have for sin hjælp.
Avatar billede arne_v Ekspert
12. april 2004 - 20:08 #11
Det kan vist ikke være mange point jeg kan tilkomme.

Men her er et svar.
Avatar billede teepee Nybegynder
12. april 2004 - 21:06 #12
Jeg lader lige spm. være åbent, for så kan jeg måske få lidt ekstra med for de samme point... og som du selv er inde på, så er din indsats måske ikke til 200 point ;-)... endnu
Avatar billede arne_v Ekspert
13. april 2004 - 07:28 #13
fair nok
Avatar billede teepee Nybegynder
13. april 2004 - 13:49 #14
Hej Arne_v. Jeg kan ikke helt få det med default tredjeparm. til at virke. Kunne jeg få dig til at skrive hele koden på én gang, altså med det som bertelbrander har skrevet? Anyway, det ser ud som om at der ikke skulle bruge mere end det allerede kodet, så jeg synes vi deler pointene lige over.
Avatar billede arne_v Ekspert
13. april 2004 - 14:04 #15
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>

using namespace std;

typedef map<int, int> MyMap;

int main(int argc, char *argv[])
{
  if(argc < 3)
  {
    cout << "usage: " << argv[0] << " file1 file2 [outfile]" << endl;
    return EXIT_FAILURE;
  }

  FILE *f = fopen(argv[2], "rt");
  if(!f)
  {
    cout << "Failed to open " << argv[2] << endl;
    return EXIT_FAILURE;
  }

  map <int, int> File2Map;
  char line[128];
  while(fgets(line, sizeof(line), f))
  {
    char *s = strtok(line, ";");
    int fv = strtol(s, 0, 10);
    s = strtok(0, "\n");
    int sv = strtol(s, 0, 10);
    File2Map.insert(make_pair(sv, fv));
  }
  fclose(f);

  f = fopen(argv[1], "rt");
  if(!f)
  {
    cout << "Failed to open " << argv[1] << endl;
    return EXIT_FAILURE;
  }

  char fnm[256];
  if(argc < 4)
  {
    strcpy(fnm, argv[1]);
    char *p = strrchr(fnm,'.');
    strcpy(p,".conv");
  }
  else
  {
    strcpy(fnm, argv[3]);
  }
  FILE *out = fopen(fnm, "wt");
  if(!out)
  {
    cout << "Failed to open " << fnm << endl;
    return EXIT_FAILURE;
  }

  while(fgets(line, sizeof(line), f))
  {
    char *fp = strtok(line, ";");
    char *mp = strtok(0, ";");
    char *lp = strtok(0, "\n");
    int v = strtol(mp, 0, 10);
    map<int, int>::iterator i = File2Map.find(v);
    if(i != File2Map.end())
    {
      fprintf(out, "%s;%d;%s\n", fp, i->second, lp);
    }
    else
      cout << "Failed to match: " << v << endl;
  }
  fclose(f);
  fclose(out);
}
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