justowanie tekstu do prawego marginesu

0

Witam,

Mam następujący problem

Z pliku odczytuje dowolny tekst, w którym może być dowolna ilość spacji między wyrazami, linijki mogą być bardzo krótkie i długie.
Problem ten już rozwiązałem. stworzyłem funkcje która do tablicy zapisuje już uporządkowany tekst. Jest to tablica jednowymiarowa, w której każde słowo jest rozdzielone spacja. Teraz muszę stworzyć funkcję, która będzie mi justować tekst do prawego marginesu, w main podaje szerokość linijki, czyli np. 30 znaków, teraz musze w każdej linijce umieścić maksymalną ilość słów, z jednakowymi odstępami. Napisałem taką funkcje, ale nie działą mi poprawnie, ma ktoś jakiś pomysł jak wykonać takie justowanie?

screenshot-20220503232406.png

3

Napisałem taką funkcje, ale nie działą mi poprawnie,

To może pokaż, co tam sobie takiego napisałeś :P

Poza tym parę pytań/kwestii/uwag:

  • co w sytuacji, gdy znajdzie się w tekście wyraz dłuższy, niż pożądana długość linii?
  • w tekście może być dowolna ilość spacji między wyrazami - ale czy one muszą zostać, czy w trakcie obróbki można je przerobić np. na pojedyncze?
  • Teraz muszę stworzyć funkcję, która będzie mi justować tekst do prawego marginesu - sprawdzasz ile znaków ma linia przed justowaniem, potem jadąc od lewej - wstawiasz spację pomiędzy wyraz 1 i 2. Jeśli nadal brakuje długości - idziesz o wyraz dalej i wstawiasz dodatkową spację między wyraz 2 i 3. I tak jedziesz albo do osiągnięcia zadanej długości, albo do wstawienia dodatkowej spacji przed ostatnim wyrazem. Jeśli wstawisz tą spację, ale nadal brakuje długości - jedziesz od początku i wstawiasz między 1 i 2, potem 2 i 3 i tak do skutku.
  • co robisz z ostatnią linia?
  • maksymalną ilość słów, z jednakowymi odstępami - to może być nierealne. Bo może się okazać że masz 7 wyrazów, a brakuje dwóch spacji do limitu. Nie ma opcji, żeby w 6 miejsc wstawić dwie spacje i żeby wszystkie dziury były jednakowe :P
0
cerrato napisał(a):

Napisałem taką funkcje, ale nie działą mi poprawnie,

To może pokaż, co tam sobie takiego napisałeś :P

funkcja main: https://pastebin.com/NmCR7zLg
funkcje operujace na moim tekscie: https://pastebin.com/U7dJEy9z

wiem, że to co napisałem funkcji do justowania, nie ma dużego sensu, stąd tez moje pytanie na forum.

  • co w sytuacji, gdy znajdzie się w tekście wyraz dłuższy, niż pożądana długość linii?

O to zadbałem już, jeśli byłaby taka sytuacja wyświetla nam ze jest to niemozliwe

  • w tekście może być dowolna ilość spacji między wyrazami - ale czy one muszą zostać, czy w trakcie obróbki można je przerobić np. na pojedyncze?

To również wykonałem, przerobiłem je na pojedyncze

  • Teraz muszę stworzyć funkcję, która będzie mi justować tekst do prawego marginesu - sprawdzasz ile znaków ma linia przed justowaniem, potem jadąc od lewej - wstawiasz spację pomiędzy wyraz 1 i 2. Jeśli nadal brakuje długości - idziesz o wyraz dalej i wstawiasz dodatkową spację między wyraz 2 i 3. I tak jedziesz albo do osiągnięcia zadanej długości, albo do wstawienia dodatkowej spacji przed ostatnim wyrazem. Jeśli wstawisz tą spację, ale nadal brakuje długości - jedziesz od początku i wstawiasz między 1 i 2, potem 2 i 3 i tak do skutku.

Próbuje od kilku dni, na różne sposoby napisać tą funkcje na różne sposoby, jak widać nieudolnie.

  • co robisz z ostatnią linia?

Ona zostaje zapisana, jak na zdjęciu z posta.

  • maksymalną ilość słów, z jednakowymi odstępami - to może być nierealne. Bo może się okazać że masz 7 wyrazów, a brakuje dwóch spacji do limitu. Nie ma opcji, żeby w 6 miejsc wstawić dwie spacje i żeby wszystkie dziury były jednakowe :P

Też o tym myślałem, i nie wiem czy nie będzie trzeba takiego wypadku zgłosić, jako błąd, że jest to niemożliwe.

1

nie wiem czy nie będzie trzeba takiego wypadku zgłosić, jako błąd, że jest to niemożliwe.

Rozumiem, że ten program robisz w ramach jakiegoś zadania na zaliczenie albo czegoś podobnego. W takim razie może daj tutaj pełną treść zadania?

0
cerrato napisał(a):

nie wiem czy nie będzie trzeba takiego wypadku zgłosić, jako błąd, że jest to niemożliwe.

Rozumiem, że ten program robisz w ramach jakiegoś zadania na zaliczenie albo czegoś podobnego. W takim razie może daj tutaj pełną treść zadania?

Tak zgadza się.

Chyba jednak, jeśli byłaby taka sytuacja, to trzeba np. odrzucic to 7 słowo, i dalej próbować umieścić identyczną ilość spacji, aż się uda

screenshot-20220504001728.png

2

Dziwny masz ten przykład

012345678901234567890123456789
Wacek ma dwie żyrafy. Józek ma
Wacek  ma  dwie  żyrafy. Józek

Jak robisz równomierny odstęp po 1 spacji to linia Wacek ma dwie żyrafy. Józek ma dokładnie 30 znaków i mieści się w linii. Jak robisz po 2 spacje na odstęp to

Wacek  ma  dwie  żyrafy.  Józek

ma 31 znaków. Żeby zatem zmieścić linię w 30 znakach przykładzie masz zatem

Wacek  ma  dwie  żyrafy. Józek

wszędzie po 2 spacje odstępu z wyjątkiem ostatniego.

0
Spearhead napisał(a):

Dziwny masz ten przykład

012345678901234567890123456789
Wacek ma dwie żyrafy. Józek ma
Wacek  ma  dwie  żyrafy. Józek

Jak robisz równomierny odstęp po 1 spacji to linia Wacek ma dwie żyrafy. Józek ma dokładnie 30 znaków i mieści się w linii. Jak robisz po 2 spacje na odstęp to Wacek ma dwie żyrafy. Józek ma 31 znaków. Żeby zatem zmieścić linię w 30 znakach przykładzie masz zatem Wacek ma dwie żyrafy. Józek - wszędzie po 2 spacje odstępu z wyjątkiem ostatniego.

Rzeczywiście nie zauważyłem tego, z tego co przeszukiwałem google, jest to przykład z jakieś strony, i treść do zadania została lekko zmieniona. I osoba zmieniająca treść zadania nie zauważyła ze tam powinny być dwie spacje, przez co finalny efekt wyglądałby inaczej.

3

Dawno dawno temu, kiedy ... pisałem takie justowanie, to podejście było mocno inne.

  1. Zrób listę z dowiązaniami aby przechowywać kolejne wiersze, na zakończenie funkcji scalisz je w jeden.
  2. Przydziel dwa robocze bufory, jeden dla kolejnego wiersza - row, drugi do kolejnego słowa word.
  3. *row='\0';
  4. Wczytujesz do word znak po znaku dopóki nie natkniesz się na biały znak lub interpunkcję (białych znak nie dopisujesz do word) lub przekroczysz rozmiar (jak przekroczyłeś rozmiar to błąd albo robisz przeniesienie)
  5. Jeżeli word jeszcze się mieści w row (razem ze spacją, jeżeli if(!*row) spacja nie jest potrzebna) to dopisujesz go do row
  6. Jeżeli word się zmieściło to przechodzisz do pkt 4 pod warunkiem że zostało w row zostało miejsce tylko na 2 znaki lub mniej.
  7. Zliczasz ilość spacji w row - spCount, oraz zliczasz ile brakuje - addCount, liczysz parityCount=(spCount>>1);
  8. Tworzysz rekord na liście line
  9. Przepisujesz z row do rekordu line do napotkania spacji (spację nie kopiujesz ale pomijasz).
  10. parityCount+=addCount+spCount; insCount=parityCount/spCount; parityCount-=insCount*spCount; dopisujesz do line insCount spacji.
  11. Jeżeli row się nie skończył to przechodzisz do pkt 9
  12. kopiujesz word do row wyczyszczasz word

Pisane z pamięci o dziejach minionych wieki temu :)

0

@_13th_Dragon: Niestety wiele z tego co napisałeś nie rozumiem. Ale spróbuje jakoś to scalić w całość i napisać. Są to dla mnie chyba zbyt zaawansowane metody, jak na moją znajomość języka C

0
The BanQ napisał(a):

edit: Są to dla mnie chyba zbyt zaawansowane metody, jak na moją znajomość języka C

http://forum.4programmers.net/C_i_C++/262765-listy_dodawanie_pierwszego_el?p=1203991#id1203991
To wszystko co potrzebujesz ponad to co masz już w kodzie.

0

A czy jest to w ogóle możliwe do napisania bez struktur? Nie używaliśmy jeszcze ich na zajęciach.

0

Masz na to 3 drogi:

  1. Wypisujesz każdy kolejny wiersz nie buforując.
  2. Tworzysz tablicę tablic i reallokujesz jak zbyt mała.
  3. Przelatujesz jeden raz "na sucho" tylko zliczając ile będzie wierszy, przydzielasz jeden raz całość i dalej piszesz do tej jednej całości.
0
_13th_Dragon napisał(a):

Masz na to 3 drogi:

  1. Wypisujesz każdy kolejny wiersz nie buforując.
  2. Tworzysz tablicę tablic i reallokujesz jak zbyt mała.
  3. Przelatujesz jeden raz "na sucho" tylko zliczając ile będzie wierszy, przydzielasz jeden raz całość i dalej piszesz do tej jednej całości.

https://pastebin.com/T85pkET8

A w ten sposób jest to możliwe żeby działało?

0

https://pastebin.com/Qs2XnvLA

Juz prawie mi się udało, zostało mi do naprawienia kilka błędów tylko
screenshot-20220504151433.png

0

Wstawiam już napisany kod do justowania jedynie za pomocą tablic. Może kiedyś się komuś przyda

void wyrownanie_do_prawej(char* text, int* dlugosci_wyrazow, int szerokosc, int ilosc_slow)
{
	printf("%s\n\n\n", text);
	
	int i;
	int ilosc_znakow_w_wierszu = 0;
	int ilosc_wyrazow_w_wierszu = 0;
	float ilosc_spacji_w_wierszu = 0;
	for (i = 1; i <= szerokosc; i++)
	{
		printf("%d", i % 10);
	}
	printf("\n");

	int j = 0;
	i = 0;
	int c;
	int x = 0;
	int var = 1;
	while (1)
	{
			if (j == ilosc_slow)
				break;

			ilosc_znakow_w_wierszu += dlugosci_wyrazow[j];
			j++;
			ilosc_wyrazow_w_wierszu++;

			if (j == ilosc_slow)
			{

				while (text[i] != NULL)
				{
					printf("%c", text[i]);
					i++;
				}
				break;
			}
			
			if (ilosc_znakow_w_wierszu == szerokosc && ilosc_wyrazow_w_wierszu == 1)
			{
				while (text[i] != ' ')
				{
					printf("%c", text[i]);
					i++;
				}
				i++;
				ilosc_wyrazow_w_wierszu = 0;
				ilosc_znakow_w_wierszu = 0;
				printf("\n");
			}
			else
			{
				while (ilosc_znakow_w_wierszu < szerokosc)
				{
					if (j == ilosc_slow)
					{
						var = 0;
						break;
					}
					ilosc_znakow_w_wierszu += dlugosci_wyrazow[j];
					j++;
					ilosc_wyrazow_w_wierszu++;
 				}
				if (var)
				{
					j--;
					ilosc_znakow_w_wierszu -= dlugosci_wyrazow[j];
					ilosc_wyrazow_w_wierszu--;
				}
					if (ilosc_znakow_w_wierszu + ilosc_wyrazow_w_wierszu - 1 == szerokosc)
				{
					for (c = 0; c < szerokosc; c++)
					{
						printf("%c", text[i]);
						i++;
					}
					printf("\n");
					i++;
					ilosc_wyrazow_w_wierszu = 0;
					ilosc_znakow_w_wierszu = 0;
				}
				else
				{
					while (1)
					{
						if (ilosc_wyrazow_w_wierszu == 1)
						{
							while (text[i] != ' ')
							{
								printf("%c", text[i]);
								x++;
								i++;
							}
							for (c = x; c < szerokosc; c++)
								printf(" ");

							printf("\n");
							i++;
							ilosc_znakow_w_wierszu = 0;
							ilosc_wyrazow_w_wierszu = 0;
							ilosc_spacji_w_wierszu = 0;
							x = 0;
							break;
						}
						else
						{
							ilosc_spacji_w_wierszu = float((szerokosc - ilosc_znakow_w_wierszu)) / (ilosc_wyrazow_w_wierszu - 1);

							if (ilosc_spacji_w_wierszu - int(ilosc_spacji_w_wierszu) == 0)
							{
								while (x != szerokosc)
								{
									if (text[i] != ' ')
									{
										printf("%c", text[i]);
										i++;
										x++;
									}
									else
									{
										for (c = 0; c < ilosc_spacji_w_wierszu; c++)
										{
											printf(" ");
											x++;
										}
										i++;
									}
								}
								i++;
								x = 0;
								printf("\n");
								ilosc_znakow_w_wierszu = 0;
								ilosc_spacji_w_wierszu = 0;
								ilosc_wyrazow_w_wierszu = 0;
								break;
							}
							else
							{
								j--;
								ilosc_znakow_w_wierszu -= dlugosci_wyrazow[j];
								ilosc_wyrazow_w_wierszu--;
							}
						}
					}
				}
			}

	}

	if(text)
		free(text);
	text = NULL;

	if(dlugosci_wyrazow)
		free(dlugosci_wyrazow);
	dlugosci_wyrazow = NULL;
}

efekt finalny. Miedzy każdym wyrazem jest jednakowa ilość spacji
screenshot-20220506174750.png

0

@MarekR22:

Sprawdziłem co napisałeś, i jest dobrze, zauważ, że linijka ma 50znaków, jeśli by znalazłoby się tam słowo "akcji" to w linijce nie będzie między każdym wyrazem tyle samo spacji

0
The BanQ napisał(a):

@MarekR22:

Sprawdziłem co napisałeś, i jest dobrze, zauważ, że linijka ma 50znaków, jeśli by znalazłoby się tam słowo "akcji" to w linijce nie będzie między każdym wyrazem tyle samo spacji

Chyba nie na tym polega justowanie tekstu, że ma być dokładnie tyle samo spacji.
Ma być tak, by zmieściło się jak najwięcej słów, a w drugiej kolejności spacje mają być rozłożone równo. U mnie nadmiarowe spacje trafiają po jednej do ostatnich odstępów.

Np twoja linijka Nick Fury, jest dość absurdalna.

0

Wtedy ma taką postać. W poleceniu jest błąd
screenshot-20220506181818.png

3

Offtopic: jeszcze raz: Dlaczego nie należy zamieszczać kodu w postaci obrazków

Tekst z takimi spacjami należy zamieszczać jako kod:

012345678901234567890123456789
Ala  ma  kota,  Tola  ma  psa.
Wacek ma dwie zyrafy. Jozek ma
trzy tygrysy, a ja  mam  tylko
pluszwego,  rozowego   slonia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1