Avatar billede cyrus2k Nybegynder
15. juli 2002 - 21:37 Der er 6 kommentarer og
2 løsninger

Fjerne dubletter fra en textfil

OK. Here goes...

Jeg skal lave en funktion der kan åbne en fil, og fjerne dubletter i den.

Filen indeholder en liste emd IP-adresser.

eks.

168.192.1.12
168.192.1.13
168.192.1.14

Osv.

Jeg havde tænkt mig noget lignende :

void Remove(char File[]){
    ifstream input_file(File,ios::in);
        if(!input_file){
          cerr << "Could not open " << 'File' << endl;
          return;
          }

        while(!input_file.eof()){
              Læs filen ind i et array - 1 linie ad gangen..
gem 1 linie i et andet array og læs 2 linie fra det 1.
Sammenlign.
Gør dette igennem hele filen.
Hvis der er dubletter, så fjern dem fra array 1.
            }
Skriv tilsidst det rettede array til en ny fil.
}

Nogle foreslag ?
Avatar billede kamikaze Nybegynder
16. juli 2002 - 09:28 #1
Du kan putte hver IP (== hver linie???) ind i en liste/vector og sammenligne med hele listen hver gang du læser en linie. Det tager lang tid, men det virker. Er det en lang fil???

// Noget lign. (pseudokode):
bool match;
while(!input_file.eof())
{
  match = false;
  læs næste linie, put i en variabel strIP;
  for alle strings i listen
  {
    sammenlign med strIP;
    Hvis findes, sæt match til true;
  }
  hvis match er false, push_back strIP på listen;
}
// Her er listen/vectoren komplet og indeholder ingen dubletter.
Avatar billede kamikaze Nybegynder
16. juli 2002 - 09:31 #2
Kender du til STL lister/vectore??? Ellers skal du vist lige have en uddybende forklaring. Kan desværre ikke lave kode, da jeg sidder midt i en analysefase på en maskine uden kompilere af nogen art!!!
Avatar billede jpk Nybegynder
16. juli 2002 - 12:00 #3
// disable warning C4786: symbol greater than 255 character,
// okay to ignore
#pragma warning(disable: 4786)

#include "stdafx.h"
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;


bool string_compare(const string& s1, const string& s2)
{
    return s1 < s2 ? 1 : 0;
}

// Return number of removed IP's or -1 on error
int Remove(char File[])
{
    // Open input file
    std::ifstream input_file(File);
    if(!input_file)
        return -1;

    char cBuffer[16];
    vector<string> IPs;

    // Read contents
    while(!input_file.eof())
    {
        input_file.getline(cBuffer, 15);
        string strIP(cBuffer);
        if(strIP.size())
            IPs.push_back(cBuffer);
    }

    input_file.close();

    if(!IPs.size())
        return 0;

    // Sort the vector so that we can easily discriminate strings
    sort(IPs.begin(), IPs.end(), string_compare);

    // Remove any dublicates
    int nRemoved=0;
    int i=0;
    vector<string>::iterator it = IPs.begin();
    ++it;
    while(i < IPs.size()-1)
    {
        if(IPs[i+1] == IPs[i])
        {
            IPs.erase(it);
            ++nRemoved;
        }
        else
        {
            ++i;
            ++it;
        }
    }

    // Write result to file
    std::ofstream output_file(File);
    for(i=0; i<IPs.size(); ++i)
    {
        output_file.write(IPs[i].c_str(), IPs[i].size());
        output_file << endl;
    }

    return nRemoved;
}


int main(int argc, char* argv[])
{
    Remove("C:\\IPs.txt");

    return 0;
}
Avatar billede cyrus2k Nybegynder
16. juli 2002 - 14:58 #4
OK. Det ser fint ud.. Jeg skal vist lige læse lidt op på vector Prog. Men jeg vender tilbage med om resultatet blev en succes.

Indtil da får i lige point, fordi Kamikaze kom først, og jpk kunne jeg mest bruge ;o)
Avatar billede kamikaze Nybegynder
17. juli 2002 - 15:17 #5
Takker for points :o)
Avatar billede soepro Nybegynder
30. juli 2002 - 14:27 #6
jpk >> Det var da vist nærmeste omvej til målet !!!

Hivs du i stedet checker om din vektor allerede indeholder den netop læste IP-adresse, kan du skrive den nye fil direkte:

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

#define  ipAddrLen 15
typedef struct
{
  char  Addr[ipAddrLen + 1]; /* Room for address + EOS */
  ipDef *Next;
  ipDef(void) { Addr[0] = '\x0'; Next = NULL; };
  ipDef(char *s) { ipDef(); strncpy(Addr, s, sizeof(Addr)-1); }
}      ipDef;

int main(void)
{
  FILE  *inpFile;
  FILE  *outFile;
  char  buffer[ipAddrLen + 3]; /* Room for ip-address, CR+LF and EOS */
 
  ipDef *readIpAddr = new ipDef;
  ipDef *ptrIpAddr;

  if ((inpFile = fopen("C:\\IPs.txt", "rb"))    == NULL
  ||  (outFile = fopen("C:\\NewIPs.txt", "wb")) == NULL)
    return -1;

  /* Loop through the lot. */
  readIpAddr = new ipDef();

  while (fgets(inpFile, buffer, sizeof(buffer)-1) != NULL)
  {
    ptrIpAddr = readIpAddr;

    /* Check if IP address already in table. */
    while (strncmp(ptrIpAddr->Addr, buffer, sizeof(ptrIpAddr->Addr)-1= != 0
      &&  ptrIpAddr->Next                                            != NULL)
    {
      ptrIpAddr = ptrIpAddr->Next;
    };

    /* If 'Next' pointer not NULL, ip address already exists. */
    if (ptrIpAddr->Next != NULL)
      /* Continue with next record. */
      continue;

    /* New IP address - put in at end of current list, and write it to the output file. */
    ptrIpAddr->Next = new ipDef(buffer);
    fputs(outFile, buffer);
  };

  /* Free list of IP-adresses. */
  do
  {
    ptrIpAddr = readIpAddr->Next;
    delete readIpAddr;
    readIpAddr = ptrIpAddr;
  } while (readIpAddr != NULL);

  /* Close both files. */
  fclose(outFile);
  fclose(inpFile);
  return 0;
} /* main */
Avatar billede jpk Nybegynder
30. juli 2002 - 14:43 #7
soepro >> Hmm, jeg havde læst opgaven som at der skulle skrives tilbage til samme fil...
(jo, man kunne selvfølgelig så have skrevet til en midlertidig fil og bagefter omdøbt osv...)
Avatar billede soepro Nybegynder
02. august 2002 - 14:18 #8
jpk >> Det skal der måske også - men derfor kunne man stadig godt sortere/indsætte løbende, og dermed undgå mellem-sorteringen. Mht. checket på om IP-adreseen allerede findes, kunne den jo så nemt ændres til at lave binær søgning, sådan at den endelige algoritme stadig kun var n*log(n)i stedet for n^2 som den er nu. (Min - ikke din, for qsort er en n*log(n) algotime.) Men så er vi vist ovre i flue-knepperiet.
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