» »

[c] Enaki datoteki

[c] Enaki datoteki

Zlatan ::

Problem je naslednji: Pišem programček, ki preveri, ali sta dve tekstovni datoteki enaki. Zadevo sem se lotil tko, da znak po znak preverja tekstovni datoteki, če se ujemata. Tole mi je uspelo do sedaj naredit:

#include<stdio.h>

int main(int argc, char *argv[])
{
FILE *prva,*druga;
prva=fopen(argv[1],"r");
druga=fopen(argv[2],"r");
int c1,c2;

while(((c1=fgetc(prva))!=EOF)||((c2=fgetc(druga)!=EOF)))
{
if(c1!=c2)
{
	printf("Datoteki nista enaki!!!\n");
	fclose(prva);
	fclose(druga);
	exit (1);
}
}

if(c1==c2)
	printf("Datoteki sta enaki!!!\n");

fclose(prva);
fclose(druga);
return 0;
}


Ko to zaženem in podam kot argumenta dve vsebinsko enaki datoteki, mi program izpiše, da datoteki nista enaki. Sedaj me pa zanima, kje je v mojem razmišljanju napaka. Edino, kar se mi zdi, da bi lahko bilo narobe, je pogoj v while zanki (mogoče ne razumem natančno, kako v tem primeru zanka teče). Ali while zanka tukaj najprej "premika" c1 za znak in šele potem, ko pride do konca, začne s c2? Ker edino v tem primeru je potem logično, da takoj javi, da sta datoteki razični...

arjan_t ::

keri imaš ali, se drugi pogoj ne bo izvedel če bo prvi pogoj true

Mitja Bonča ::

A to misliš prav popolnoma enaki? Do byta natančno? Ali samo po texstu znotraj datoteke?
Če misliš po bytih natančni je to to: (samo se napisal program v C#)ž
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace EnakiDatoteki
{
    class Program
    {
        static void Main(string[] args)
        {
            string potDatoteke1 = @"C:\2\ListaStrank.txt";
            string potDatoteke2 = @"C:\2\3\ListaStrank.txt";

            string imeDatoteke1 = System.IO.Path.GetFileName(potDatoteke1);
            string imeDatoteke2 = System.IO.Path.GetFileName(potDatoteke2);

            long velikostDatoteke1 = new FileInfo(potDatoteke1).Length;
            long velikostDatoteke2 = new FileInfo(potDatoteke2).Length;

            //ČE SE DATOTEKI UJEMATA PO ŠTEVILU BITOV SE PRIMERJA ŠE VSAK POSAMEZEN BIT POSEBEJ:
            if (velikostDatoteke1 == velikostDatoteke2)
            {
                bool boolEnakiDatoteki = false;
                byte[] štByteDatoteke1 = null;
                byte[] štByteDatoteke2 = null;
                FileStream fs1 = new FileStream(potDatoteke1, FileMode.Open, FileAccess.Read);
                FileStream fs2 = new FileStream(potDatoteke2, FileMode.Open, FileAccess.Read);
                BinaryReader br1 = new BinaryReader(fs1);
                BinaryReader br2 = new BinaryReader(fs2);
                štByteDatoteke1 = br1.ReadBytes((int)velikostDatoteke1);
                štByteDatoteke2 = br2.ReadBytes((int)velikostDatoteke2);

                //PRIMERJA SE VSAK BIT 1. DATOTEKE Z BITOM V DRUGI DATOTEKI
                int števec=0;
                foreach (byte enByte1 in štByteDatoteke1)
                {
                    byte enByte2 = štByteDatoteke2[števec];
                    if (enByte1 != enByte2)
                    {
                        Console.WriteLine("Datoteki {0} in {1} nista enaki.", imeDatoteke1, imeDatoteke2);
                        break;
                    }
                    else
                        boolEnakiDatoteki = true;
                    števec++;
                }
                if (boolEnakiDatoteki)
                    Console.WriteLine("Datoteki {0} in {1} sta popolnoma identični.", imeDatoteke1, imeDatoteke2);
            }
            else
                Console.WriteLine("Datoteki {0} in {1} nista enaki.", imeDatoteke1, imeDatoteke2);
            Console.ReadLine();
        }
    }
}

Mitja Bonča ::

Tako pa je če hočeš primerjati samo besedilo (čisti tekst v datoteki):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace EnakiDatoteki
{
    class Program
    {
        static void Main(string[] args)
        {
            string potDatoteke1 = @"C:\2\ListaStrank.txt";
            string potDatoteke2 = @"C:\2\3\ListaStrank.txt";

            string imeDatoteke1 = System.IO.Path.GetFileName(potDatoteke1);
            string imeDatoteke2 = System.IO.Path.GetFileName(potDatoteke2);

            long velikostDatoteke1 = new FileInfo(potDatoteke1).Length;
            long velikostDatoteke2 = new FileInfo(potDatoteke2).Length;

            //ČE SE DATOTEKI UJEMATA PO ŠTEVILU BITOV SE PRIMERJA ŠE VSAK POSAMEZEN BIT POSEBEJ:
            if (velikostDatoteke1 == velikostDatoteke2)
            {
                int števec = 0;
                bool boolEnakiDatoteki = false;
                string a = System.IO.File.ReadAllText(potDatoteke1);
                string b = System.IO.File.ReadAllText(potDatoteke2);
                string[] vrsticeDatoteke1 = System.IO.File.ReadAllLines(potDatoteke1);
                string[] vrsticeDatoteke2 = System.IO.File.ReadAllLines(potDatoteke2);

                foreach (string enZnak1 in vrsticeDatoteke1)
                {
                    string enZnak2 = vrsticeDatoteke2[števec];
                    if (enZnak1 != enZnak2)
                    {
                        Console.WriteLine("\tBesedilo datoteke {0}\n\tse ne ujema z\n\tbesedilom iz datoteke {1}.", imeDatoteke1, imeDatoteke2);
                        break;
                    }
                    else
                        boolEnakiDatoteki = true;
                    števec += 1;
                }
                if (boolEnakiDatoteki)
                    Console.WriteLine("\tBesedilo v datoteki {0}\n\tje popolnoma enako\n\tbesedilu iz datoteke {1}.", imeDatoteke1, imeDatoteke2);
            }
            else
                Console.WriteLine("\tBesedilo datoteke {0}\n\tse ne ujema z\n\tbesedilom iz datoteke {1}.", imeDatoteke1, imeDatoteke2);
            Console.ReadLine();
        }
    }
}

Upam da kaj pomaga, ker jaz nisem za C (še) :)

napsy ::

Malo popravljena zgornja koda:

#include<stdio.h>

int main(int argc, char *argv[])
{
    FILE *prva,*druga;
    int razlicna = 0;

    if (argc < 3)
        return 1;

    prva=fopen(argv[1],"r");
    druga=fopen(argv[2],"r");
    if (!prva || !druga)
        return 1;

    int c1,c2;

    while(1) {
        c1=fgetc(prva);
        c2=fgetc(druga);
        if (c1 == EOF) {
            if (c2 != EOF)
                razlicna = 1;
            break;
        }
        else if (c2 == EOF) {
            if (c1 != EOF)
                razlicna = 1;
            break;
        }
        if(c1!=c2)
        {
            razlicna = 1;
            break;
        }
    }

    if (razlicna)
        printf("Datoteki nista enaki!!!\n");
    else
        printf("Datoteki sta enaki!!!\n");

    fclose(prva);
    fclose(druga);
    return 0;
}
"If you die, you die. But when you live you live. There is no time to waste."

Tutankhamun ::

če že bereš znak po znak, pa na začetku lahko še preveriš če sta datoteke sploh enake velikosti, da ti že prej vn skoč.

int main(int argc, char* argv[])
{
	int	c1, c2;
	FILE	*prva, *druga;

	prva = fopen("d:\\prva.txt", "r");
	druga = fopen("d:\\druga.txt", "r");
	
	do {
		c1 = fgetc(prva);
		c2 = fgetc(druga);

		if (c1 != c2) {
			printf("Datoteki nista enaki!!!\n");
			break;
		}

	} while(c1 != EOF);

	if (c1 == c2)
		printf("Datoteki sta enaki!!!\n");

	fclose(prva);
	fclose(druga);

	return 0;
}

int main(int argc, char* argv[])
{
	static const int SIZE = 1024*4;

	char	c1[SIZE], c2[SIZE];
	int		sz1, sz2;
	FILE	*prva, *druga;
	int		razlika = 0;

	prva = fopen("d:\\prva.txt", "r");
	druga = fopen("d:\\druga.txt", "r");
	
	do {
		sz1 = fread(c1, sizeof(char), SIZE, prva);
		sz2 = fread(c2, sizeof(char), SIZE, druga);

		if (sz1 != sz2) {
			razlika = 1;
			break;
		}

		if (sz1 == 0) break;

		if (memcmp(c1, c2, sz1) != 0) {
			razlika = 1;
			break;
		}

	} while(1);

	if (razlika == 0)
		printf("Datoteki sta enaki!!!\n");
	else
		printf("Datoteki nista enaki!!!\n");

	fclose(prva);
	fclose(druga);

	return 0;
}
AMD Phenom QUAD 9950 Black Edition, 8GB

Zgodovina sprememb…

Zlatan ::

Uff, ste že več pomagali, kot bi blo treba :) Ja, datoteki se primerjata po vsebini (po tekstu v datoteki). Hvala vsem!!!

Spura ::

Dej ti malo uporablji buffer, ker tole ti bo 100 let delal, ce bos znak po znaku bral. Preberi 1 mb naekrat naprimer, bo veliko hitreje delal. Res pa je, da mogoce sodobni diski tako ali tako bufferajo...samo se vedno je to pocasno, ker je branje z diska sistemski klic.

Zgodovina sprememb…

  • spremenil: Spura ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

C# pomoč pri razmišljanju

Oddelek: Programiranje
352174 (1318) urozz
»

[C] Branje iz datoteke

Oddelek: Programiranje
101647 (1478) BigWhale
»

bash programiranje

Oddelek: Programiranje
61398 (1218) snow
»

[Naloga][C++] podatkovni tip sklad in istoležne vrstice v datotekah

Oddelek: Programiranje
81950 (1819) matjaz1111
»

[C++][Naloga] Tekstovne datoteke, realna števila

Oddelek: Programiranje
253864 (3480) Gundolf

Več podobnih tem