Program do dzielenia tekstu na części

0

Witam.
Program ma dzielić ciąg znaków wprowadzany z klawiatury na części, co 50 znaków. W każdej części mają być usunięte białe znaki na końcu. Oto kod, który napisałem:

#include <stdio.h>

#define MAXCHARS 2000 /* maksymalna liczba znaków w danych wejściowych */
#define STEP 50 /* co ile znaków są różne części */

int wczytaj(char s[]); /* wczytaj: wczytuje ciąg znaków do 's' */
void add(char to[], char from[]); /* add: dodaje do ciągu znaków 'to' ciąg 'from' */
void podziel(char s[]); /* podziel: dzieli tekst na częsci, co 'STEP' znaków */
void zeruj(char s[]); /* zeruj: wypełnia ciąg znaków 's' zerami - EOF */
void copy(char  to[], char from[]); /* copy: kopiuje ciąg znaków 'from' do ciągu znaków 'to' */

main()
{
	char ciag[MAXCHARS]; /* ciąg znaków wczytywany z klawiatury */

	wczytaj(ciag);
	podziel(ciag);
	printf("%s", ciag);
	return 0;
}

int wczytaj(char s[])
{
	int	c;
	int	i;

	for (i = 0; (c = getchar()) != EOF && i < MAXCHARS; ++i)
		s[i] = c;
}

void add(char to[], char from[])
{
	int i;
	int j;
	char tekst[] = "\n\n---------- NOWA CZĘŚĆ ----------\n\n";
	int len;

	len = sizeof(tekst) / sizeof(char);

	i = MAXCHARS - 1;
	while (i >= 0 && to[i] == EOF)
		--i;
	++i;
	for (j = 0; (i + j) < MAXCHARS; ++j) {
		if (from[j] == EOF)
			break;
		to[i+j] = from[j];
	}

	i = j;
	
	for (j = 0; (i + j) < MAXCHARS && j < len; ++j)
		to[i+j] = tekst[j];
}

void podziel(char s[])
{
	int i;
	int j;
	char czesc[STEP];
	char ciag[MAXCHARS];

	for (i = 0; i < MAXCHARS; i += STEP) {
		for (j = 0; j < STEP; ++j)
			czesc[j] = s[i+j];
		j = MAXCHARS - 1;
		while (j >= 0 && (czesc[j] == ' ' || czesc[j] == '\t' || czesc[j] == '\n'))
			--j;
		++j;
		for (j = 0; j < MAXCHARS; ++j)
			czesc[j] = EOF;
		add(ciag, czesc);
		zeruj(czesc);
	}
	copy(s, ciag);
}

void zeruj(char s[])
{
	int i;
	int len; /* długość ciągu 's' */

	len = sizeof(s) / sizeof(char);
	for (i = 0; i < len; ++i)
		s[i] = EOF;
}

void copy(char to[], char from[])
{
	int i;

	i = 0;
	while ((to[i] = from[i]) != EOF)
		++i;
}

Po uruchomieniu, wprowadzeniu tekstu i znaku EOF program zostaje przerwany i w konsoli jest ten tekst:

*** stack smashing detected ***: ./dziel terminated
Naruszenie ochrony pamięci

System: Linux
Kompilator: GCC 4.6.1
Z góry dziękuję za pomoc w znalezieniu błędu.

0

tak na pierwszy rzut oka, w funkcji wczytaj nie dopisujesz znaku '\0' na końcu napisu.

0

No wydawało mi się, że tablice char od razu są wypełnione takimi znakami, ale skoro nie, to poprawiłem: http://4programmers.net/Pastebin/1700. Nadal to samo.

1

W funkcji podziel() masz pod koniec pętlę:

for (j = 0; j < MAXCHARS; ++j)
	czesc[j] = EOF;

Tylko że tablica czesc[] ma długość STEP, a ty lecisz w pętli aż do MAXCHARS.
Tylko jaki sens ma zerowanie tablicy przed jej skopiowaniem?

0

Dobra. Poprawione: http://4programmers.net/Pastebin/1701.

mar-ek1 napisał(a)

W funkcji podziel() masz pod koniec pętlę:

for (j = 0; j < MAXCHARS; ++j)
	czesc[j] = EOF;

Tylko że tablica czesc[] ma długość STEP, a ty lecisz w pętli aż do MAXCHARS.
Tylko jaki sens ma zerowanie tablicy przed jej skopiowaniem?

Najpierw dodaję tablicę, w której jest pojedyncza część tekstu do innej tablicy dołączając do niej tekst "---------- NOWA CZĘŚĆ ----------", później zeruję tablicę, która zawiera pojedynczą część tekstu, jest kolejna pętla i na nowo zaczyna się zapisywanie do tablicy czesc[]. Jak skończy się wykonywanie pętli, to tablica z podzielonym już tekstem kopiuje się do tablicy podanej w argumencie funkcji podziel().

Tylko, że teraz drukuje tylko "---------- NOWA CZĘŚĆ ----------".

0

Już wiem, że problem jest w tym, że pętla z linii 42 nie wykonuje się ani razu. Wie ktoś może dlaczego?

0

Poprawiłem ten program. Teraz wszystko działa ładnie, pięknie oprócz funkcji czyscbiale. Bez niej wszystko jest dobrze, tylko, że nie czyści białych znaków z końca każdej części. Z kolei razem z nią czyści aż za dużo.
Oto poprawiony kod: http://4programmers.net/Pastebin/1716.

1

sizeof(s) nie zwróci ci rozmiaru tablicy przekazanej do funkcji.
Poza tym są problemy z wielkością buforów.
http://4programmers.net/Pastebin/1717

0

Twój przykład mi nie zadziałał tak jak powinien nawet po poprawieniu prototypów funkcji, ale dzięki za wskazówkę z tym sizeof. Poprawiłem to tak: http://4programmers.net/Pastebin/1719 i działa.

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