Forum » Programiranje » [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:
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...
#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...

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#)ž
Č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):
Upam da kaj pomaga, ker jaz nisem za C (še) :)
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…
- spremenil: Tutankhamun ()

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 ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | C# pomoč pri razmišljanjuOddelek: Programiranje | 2336 (1480) | urozz |
» | [C] Branje iz datotekeOddelek: Programiranje | 1741 (1572) | BigWhale |
» | bash programiranjeOddelek: Programiranje | 1488 (1308) | snow |
» | [Naloga][C++] podatkovni tip sklad in istoležne vrstice v datotekahOddelek: Programiranje | 2037 (1906) | matjaz1111 |
» | [C++][Naloga] Tekstovne datoteke, realna številaOddelek: Programiranje | 4074 (3690) | Gundolf |