Skocz do zawartości
Guardian_McLeavy

[c++] Zapisywanie I Czytanie Bianrne Struktury

Rekomendowane odpowiedzi

Witam! Pisałem dosyć dawno temu koder, i zaprzestałem, ponieważ zatrzymałem się na momęcie, którego nie potrafie rozwiązać. Może wy coś poradzicie.

Działanie programu:

Wprowadza się tekst do kodowania. Program losuje "mnoznik", który zapisuje do struORT: ORT: ORT: ktury. Następnie przekształća po kolei znaki tekstu, na kod, tzn. dodaje do numeru znaku w ASCII wylosowany mnoznik. Po tym zapisuje całą strkturę, zawierającą kod i mnożnik do pliku (binarnie). I do tąd chodzi (bynajmniej pojawiają się ślaczki w pliku tekstowym). Problem jest z odkodowaniem, bo wtedy funkcja się sypie. Wykonuje w nieskończoność pętle. Czy ktoś wie gdzie leży błąd?

Oto kod programu:

#include <stdio.h>#include <stdlib.h>#include <math.h>void Zakoduj(char* before, int* after, int a);void Odkoduj(char* before, int* after, int a);int main(){	struct KOD	{		int kod[100];		int przelicznik;	};	KOD podaj;	char tresc[100];	printf("Koder objektowy by Guardian\nWybierz:\n");	printf("1. Koduj");	printf("2. Dekoduj");	int opcja;	scanf("%d", &opcja);	if(opcja == 1)	{		printf("Podaj tresc do kodowania:\n");		scanf("%s", &tresc);		int x = (int) rand() % 21;		podaj.przelicznik = (int) pow(2,(double) x);		Zakoduj(tresc, podaj.kod, x);		//Zapis binarny		FILE* plik = fopen("kod.dat","wb");		fwrite(&podaj,1, sizeof( KOD ), plik);		fclose(plik);	}	else	{		FILE* plik = fopen("kod.dat","rb");		fread(&podaj,1, sizeof( KOD ), plik);		fclose(plik);		Odkoduj(tresc, podaj.kod, podaj.przelicznik);		printf("%s", &tresc);	}	return 0;}void Zakoduj(char* before, int* after, int a){	int bufor;	for(int i = 0; i < 100; i++)	{		bufor = before[i];		after[i] = bufor + a;	}}void Odkoduj(char* before, int* after, int a){	int i = 1;	int bufor;	while(1)	{		if(pow(a,1/i) == 2) break;		i++;	}	for(int i = 0; i < 100; i++)	{		bufor = after[i];		before[i] = (int) after - a;	}}

Z góry dziękuję za pomoc!

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Odpowiedzi gotowej nie podam bo nie mam trochę czasu, ale wiesz chyba że błąd jest tu:

while(1)	{		if(pow(a,1/i) == 2) break;		i++;	}

Widocznie pow(a,1/i) nigdy nie osiąga u Ciebie wartości 2....

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Witam! Pisałem dosyć dawno temu koder, i zaprzestałem, ponieważ zatrzymałem się na momęcie, którego nie potrafie rozwiązać. Może wy coś poradzicie.

(...)

Czy ktoś wie gdzie leży błąd?

Uf błędów tutaj sporo, ale po kolei

 

if(opcja == 1)	{		printf("Podaj tresc do kodowania:\n");		scanf("%s", &tresc);
źle, winno być scanf("%s",tresc); nazwa tablicy może być użyta jako wskaźnik na pierwszy element

po &tresc masz wskaźnik na wskaźnik na pierwszy element

 

Odkoduj(tresc, podaj.kod, podaj.przelicznik);		printf("%s", &tresc);
źle, jak wyżej, printf("%s",tresc)

 

 

void Zakoduj(char* before, int* after, int a){	int bufor;	for(int i = 0; i < 100; i++)	{		bufor = before[i];		after[i] = bufor + a;
bufor ci nie potrzebny, nie można tak?: after = before + a;

 

void Odkoduj(char* before, int* after, int a){	int i = 1;	int bufor;	while(1)	{		if(pow(a,1/i) == 2) break;		i++;	}
i co po tej pętli ? nic, masz swój klucz w i, którą za chwile nadpiszesz

daj np. a = i; głupio wygląda ale działa

 

for(int i = 0; i < 100; i++)	{		bufor = after[i];		before[i] = (int) after - a;
a tutaj masakra,

rzutujesz wskaźnik (pierwszy element tablicy) na int, odejmujesz a i zapisujesz jako i-ty element w tablicy charów

spróbuj before = (char)(after - a);

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Wprowadziłem zmiany. Te początkowe to były niekonieczne, ale faktycznie, poprawiają jakościowo kod. I problem z funkcją odkoduj. Dalej się "zacina" :/

Masz w załączniku poprawioną wersję. U mnie działa, kompilator poniżej

~/temp$ g++ --version

g++ (GCC) 3.4.5 (Gentoo 3.4.5-r1, ssp-3.4.5-1.0, pie-8.7.9)

koder.txt

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ten post zostawie na przyszlosc. Dzialo sie tak prawdopodobnie dla tego, ze 1/i nie musi dawac poprawnych wynikow. Tzn 1/2 nie oznacza koniecznie 0.5, moze byc np 0.4999999999999999. Wynika to z faktu iz obliczenia zmiennoprzecinkowe sa zawsze podawane z pewna dokladnoscia. Aby sprawdzic ile ta dokladnosc wynosi(zalezy od typu) mozna uzyc std::numeric_limits<T>::epsilon(). Dla float bedzie to: std::numeric_limits<float>::epsilon().

 

Wiecej info jest tu.

 

Pozdr!

novo.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...