Laboratorium programowania zad 13

Zadanie z laboratorium programowania na Informatyce UW.

Zadanie 13 (termin wysylania rozwiazan: 7 maja 2008, godz. 23:59)

(Kodowanie)

Spacje i tabulacje znajdujace sie na koncu wiersza pliku tekstowego
nie sa widoczne dla osoby czytajacej tekst. Mozna to wykorzystac do
ukrywania w tekscie informacji. Np. jeden bajt mozemy zakodowac w
tekscie, umieszczajac na koncu wiersza osiem znakow: spacje (oznaczajace
bit 0) i tabulacje (oznaczajace bit 1). Przyjmiemy, ze bity beda
uporzadkowane w kolejnosci od najbardziej znaczacego.

Napisz program ktory, w zaleznosci od sposobu wywolania, ukryje
w kolejnych wierszach tekstu po jednym bajcie pliku binarnego, lub
odczyta je z tekstu.

Program bedzie wywolywany z dwoma argumentami - litera 'c' lub 'd'
oznaczajaca tryb pracy, oraz nazwa pliku binarnego.

Program wywolany poleceniem:

./zsi07z13 c binaria wynik

ma zakodowac zawartosc pliku binarnego o nazwie "binaria" w tekscie
wczytanym z wejscia (tu jest nim zawartosc pliku o nazwie "tekst") i
wypisac na wyjscie wynik kodowania (w tym wypadku wynik trafi do pliku
o nazwie "wynik").

Niech liczba wierszy tekstu wejsciowego bedzie rowna K, a liczba bajtow
pliku binarnego N.

Jesli K jest wieksze lub rowne N, N poczatkowych wierszy tekstu wynikowego
ma zawierac reprezentacje kolejnych bajtow, a pozostalych K-N wierszy
nalezy skopiowac z wejscia na wyjscie bez zmian.

Jesli K jest mniejsze niz N postepujemy tak, jakby na koncu tekstu
wejsciowego bylo dodatkowo N-K wierszy pustych.

Program wywolany poleceniem:

./zsi07z13 d binaria <tekst

ma odkodowac dane ukryte w tekscie wczytanym z wejscia (tu jest nim
zawartosc pliku "tekst") i zapisac je w pliku binarnym o nazwie "binaria".

Zakladamy, ze tekst wejsciowy dla tego wywolania programu zawiera poprawnie
zakodowana informacje. Oznacza to, ze N poczatkowych wierszy tego tekstu
konczy sie osmioma znakami spacji i tabulacji. Jesli tekst wejsciowy ma
wiecej niz N wierszy, na koncu wiersza o numerze N+1 nie ma osmiu znakow
spacji i tabulacji. Program powinien utworzyc plik "binaria" i zapisac do
niego N odczytanych bajtow.

W zalacznikach do tresci sa pliki przykladowe:

zsi07z13.binaria
zsi07z13.tekst1
zsi07z13.tekst2
zsi07z13.wynik1
zsi07z13.wynik2

pasujace do ciagu wywolan programu:

./zsi07z13 c zsi07z13.binaria zsi07z13.wynik1
./zsi07z13 d zsi07z13.binaria <zsi07z13.wynik1
./zsi07z13 c zsi07z13.binaria zsi07z13.wynik2
./zsi07z13 d zsi07z13.binaria <zsi07z13.wynik2

A oto rozwiązanie:

#include 
#include 
#include 

//bufor - jeden bajt zapisany tym specyficznym sposobem.
char bufor[8];

int rozkoduj ()
{
	//koduje ciag spacji i tabulacji na liczbe w kodzie U2 od najbardziej znaczacego bitu.
	int i,wynik,mnoznik;
	
	//dla ujemnego bitu:
	if (bufor[0]=='t')
	{
		wynik=-128;
	}
	else
	{
		wynik=0;
	}
	
	mnoznik=64; 
		
	//7 razy:
	for (i=1;i<8;i++)
	{
		if(bufor[i]=='t')
		{
			wynik=wynik+mnoznik;
		}
		
		mnoznik=mnoznik/2;
	}

	return wynik;

}

int zakoduj (int liczba)
{
	//koduje liczbe znak na ciag spacji i tabulacji.
	//Oczywiscie W ZADANIU NIE NAPISANO ZE KOD JEST UZUPELNIENIOWY DO 2!! MUSIELISMY SIE SAMI DOMYSLIC!!
	int i,wynik,mnoznik;
	
	//na poczatku dla ujemnego bitu:
	
		if (liczba<0)
		{
			liczba=liczba+128;
			bufor[0]='t';
		}
		else
		{
			bufor[0]=' ';
		}
		
	
	mnoznik=64; 
	wynik=0;
		
	
	//7 razy:
	
	for (i=1;i=mnoznik)
		{
			//ta liczba jest w rozkladzie.
			bufor[i]='t';
			liczba=liczba-mnoznik;
		}
		else
		{
			bufor[i]=' ';
		}
		
		mnoznik=mnoznik/2;
	}
	
	return 0;

}



int main (int argc,char *argv[])
{
	FILE * f;
	char znak,binarny;
	int wynik, wynikb, bufor_index, i;

	//Argumanry wywolania
	if(argv[1][0]=='c')
	{// czyli musimy zakodowac tekst
		//printf("%s",argv[2]);
		f=fopen(argv[2],"rb");
		
		wynik=scanf("%c",&znak);
		wynikb=fscanf(f,"%c",&binarny);
		
		while(wynik!=EOF)
		{
			if(znak=='r')
			{
				//nic nie robimy. to zle znaki sa.
			}
			else if (znak=='n')
			{
				//kodujemy
				//jesli jest co kodowac.
				
				if(wynikb!=EOF)
				{
					//printf("[%d]",binarny);
					zakoduj(binarny);
					printf("%s",bufor);
					wynikb=fscanf(f,"%c",&binarny);
				}
				//i koniec linii:
				printf("n");
			}
			else
			{
				//przepisujemy znak.
				printf("%c",znak);
			}
			wynik=scanf("%c",&znak);
		} // ok. caly tekst zrodlowy przepisalismy
		
		//Jesli jeszcze cos do zakodowania:
		
		while(wynikb!=EOF)
		{
			zakoduj((int) binarny);
			printf("%s",bufor);
			//printf("[%d]",binarny);
			wynikb=fscanf(f,"%c",&binarny);
			//i koniec linii:
			printf("n");

		}
		//zamykamy binaria
		fclose(f);
	}
	else if(argv[1][0]=='d')
	{//bedziemy dekodowac
	
		f=fopen(argv[2],"wb");
		wynik=scanf("%c",&znak);
		
		while(wynik!=EOF)
		{
			if(znak=='r')
			{
				//nic nie robimy. to zle znaki sa.
			}
			else if((znak=='t')||(znak==' '))
			{
				//mamy jeden z tajemnych znakow. przepisujemy do bufora.
				if (bufor_index<8)
				{
					bufor[bufor_index]=znak;
					bufor_index++;
				}
				else if (bufor_index==8)
				{
					//dziwna sytuacja. Znaczy ze na koncu tekstu byly biale znaki i do tego zostalo cos dokodowane. musimy przesunac bufor,
					for (i=0;i<7;i++)
					{
						bufor[i]=bufor[i+1];
					}
					bufor[7]=znak;
					//bufor przesuniety,
										
				}
			}
			else if (znak=='n')
			{
				//rozkodowujemy.
				
				if(bufor_index==8) //rowniotko 8 bitow.
				{
					binarny=rozkoduj();
					fprintf(f,"%c",binarny);
				}
				//printf("n");
			}
			else
			{
				//przepisujemy znak i zerujemy bufor.
				bufor_index=0;
				//printf("%c",znak);
			}
			
			wynik=scanf("%c",&znak);
		}

		fclose(f);
	}

return 0;
}

Leave a Reply