Program znajdujacy wyrazy z 'h' i 'e'

0

Witam,
mam do napisania program, ktory ma znajdowac i wyswietlac wyrazy z literami 'h' i 'e' obok siebie. Moze ma ktos pomysl, dlaczego nie dziala tak jak powinnio?

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define CHUNK 12

char *getWord(FILE *infile);
int selection(char *word, int length);

int main(int argc, char *argv[])
{
	char *word, c;
	FILE *infile, *outfile;
	
	if(argc < 2)
	{
		printf("%s","\nMissing arguments.\n");
		abort();
	}
	
	infile = fopen(argv[1], "r");
	if(infile != NULL)
	{
		outfile = fopen(argv[2], "w");
		if(outfile == NULL)
		{
			printf("It is impossible to open outfile\n");
			abort();
		}
		else
		{
			while(!feof(infile))
			{
				word = getWord(infile);
				if(word == NULL)
				{
					free(word);
					break;
				}
				selection(word, strlen(word));
				fputs(word, outfile);
				if((c = getc(infile)) != EOF)
					putc(c, outfile);
				free(word);
			}
		}
	}
	else
	{
		printf("It is impossible to open the infile\n");
		abort();
	}
	
	fclose(infile);
	fclose(outfile);
	
	return 0;
}

char *getWord(FILE *infile)
{
	int length1, c, cursor;
	char *word, *word2;
	
	word = malloc(sizeof(char)*CHUNK);
	if(word == NULL) return NULL;
	
	length1 = CHUNK;
	cursor = 0;
	
	while(isalpha(c = getc(infile)))
	{
		word[cursor] = c;
		cursor++;
		
		if(cursor >= length1)
		{
			length1 += CHUNK;
			word2 = realloc(word, length1*sizeof(char));
			
			if(word2 == NULL) 
			{
				free(word2);
				return NULL;
			}
			else word2 = word;
		}
	}
	ungetc(c, infile);
	word[cursor] = '\0';
	return word;
}

int selection(char *word, int length)
{
	int i;
	for(i = 0; i < length-1; i++)
		if(word[i] == 'h' && word[i+1] == 'e')
			return 0;
		return 1;
}

Generalnie, mam 2 problemy. Albo program przepisuje caly tekst albo wyswietla wyrazy, ktore chce ale bierze tez spacje.

0

Funkcja selection zwraca Ci wynik wyszukiwania - 0 lub 1. Ty jednak z tym nic nie robisz. Ot wywolujesz funkcje ktora powinna Ci powiedzieć czy coś znalazła i nie interesuje Cię odpowiedź.
To tak z grubsza odnośnie samej idei. Poza tym - przy pętli for użyj nawiasów, bo przynajmniej dla mnie na pierwszy rzut oka jest nieczytelny.

0

Okay, faktycznie. Oto zmieniony main.

 
int main(int argc, char *argv[])
{
	char *word, c;
	int pointer;
	FILE *infile, *outfile;
	
	if(argc < 2)
	{
		printf("%s","\nMissing arguments.\n");
		abort();
	}
	
	infile = fopen(argv[1], "r");
	if(infile != NULL)
	{
		outfile = fopen(argv[2], "w");
		if(outfile == NULL)
		{
			printf("It is impossible to open outfile\n");
			abort();
		}
		else
		{
			while(!feof(infile))
			{
				word = getWord(infile);
				if(word == NULL)
				{
					free(word);
					break;
				}
				pointer = 0;
				while(selection(word, strlen(word)) == 0)
				{
					if(word[pointer] == '\0')
					{
						fputs(word, outfile);
						fputs("\n", outfile);
						break;
					}
					pointer++;
				}
				pointer = 0;
				if((c = getc(infile)) != EOF)
					putc(c, outfile);
				free(word);
			}
		}
	}
	else
	{
		printf("It is impossible to open the infile\n");
		abort();
	}
	
	fclose(infile);
	fclose(outfile);
	
	return 0;
}

Ale nadal mam jeden problem. Wyrazy wyswietlaja mi sie wraz ze spacjam z przodu i z tylu (mimo, iz w getWord'zie mam wyjatek !isspace). Przesylam screen'a z problemem.

0

Proponuję abyś to zrobił w oparciu o ten przykład:

#include <stdio.h>
#include <string.h>
int main ()
{
	char str[] ="moher rudy setler heban japonia";
	char *pch, *lol = NULL;
	pch = strtok (str," ,.-");
	while (pch != NULL)
	{
		lol = strstr (pch,"he");
    	if(lol != NULL)
    		printf ("%s ",pch);
    	pch = strtok (NULL, " ,.-");
  	}
  	return(0);
}
0

Pytam z czystej ciekawości. Egzamin u GWJ? :>

0

yyyeey tak przygotowuje sie do Grzesia :>
Kaaaaaaaaamil okay, dzieki, zaraz siadam i postaram sie zmienić.

0

Nie wiem czy miałeś przyjemność odbyć wnikliwe testy, ale przygotuj się nawet na losowe stringi składające się ze wszystkich znaków, które tylko nawiną się pod palce. Radzę zapoznać się ze wszystkimi funkcjami pokroju isAlpha(c), isDigit(c), itp. Z egzaminu na egzamin zwykle jest coraz ciężej, może pojawić się polecenie typu usuwaj wyraz po słowie zawierającym 'e' lub 'he'. Niektórym stwarza to ogromne problemy.

0

yyyeey mielismy, wlasnie przez te "przyjemne" testy, udalo nam sie nie zaliczyc.
Kaaaaaaaaami mam problem, tzn. zmienilem tak jak powiedziales i dobrze wyswietla mi w konsoli ale juz w pliku tekstowym jest tak samo jak wtedy.

int main(int argc, char *argv[])
{
	char *word, c;
	/*int pointer;*/
	char *sign, *sign2 = NULL;
	FILE *infile, *outfile;
	
	if(argc < 2)
	{
		printf("\nMissing arguments.\n");
		abort();
	}
	
	infile = fopen(argv[1], "r");
	if(infile != NULL)
	{
		outfile = fopen(argv[2], "w");
		if(outfile == NULL)
		{
			printf("It is impossible to open outfile\n");
			abort();
		}
		else
		{
			while(!feof(infile))
			{
				word = getWord(infile);
				if(word == NULL)
				{
					free(word);
					break;
				}
				
				sign = strtok(word, " ,.-");
				while(sign != NULL)
				{
					sign2 = strstr(sign, "he");
					if(sign2 != NULL)
						fprintf(outfile, "%s\n", sign);
					sign = strtok(NULL, " ,.-");
				}
				
				if((c = getc(infile)) != EOF)
					putc(c, outfile);
				free(word);
			}
		}
	}
	else
	{
		printf("It is impossible to open the infile\n");
		abort();
	}
	
	fclose(infile);
	fclose(outfile);
	
	return 0;
}

Jakas sugestia ?

0

Mi twój kod działa, jedynie przeszkadza, że w każdym wywołaniu fprintf dodajesz znak nowej linii, ale może tak było w specyfikacji tym razem. Jesteś pewien, że myślniki rozdzielają słowa? Gdy ja podchodziłem do tego egzaminu były traktowane jako jedno, możliwe, że dla urozmaicenia się to zmieniło, jednak sprawdź to. Z dodatkowych błędów, które nie mają wpływu na wynik programu jest przede wszystkim to, że gdy już otworzysz jeden plik i sprawdzasz drugi, przy ewentualnym błędzie programu, nie zamykasz tego pierwszego, podobnie z malloc'iem i realloc'iem w funkcji getWord. Sprawdź Valgrindem, jeżeli bedą memory leaki to niestety też nie zaliczysz. GWJ może się również przyczepić o nazwę funkcji, gdyż pobiera ona całą linię a nie słowo, więc powinna być getLine. Innym elementem, który może jeszcze nie pasować jest użycie free(ptr) w instrukcji warunkowej, w której wiesz że ten wskaźnik jest i tak NULL'owy. W takim przypadku funkcja po prostu nic nie robi, ni to wada, ni zaleta, jednak Grzesiowi może nie pasować, że karzesz programowi robić coś bez powodu, odjął mi kiedyś za coś podobnego punkty.

0

yyyeey dzieki za pomoc, sprawdze. Bede sie jeszcze odzywal, mam do przerobienia kilka zadan. Btw. tak z ciekawosci CS czy TCS?

0

CS, ale inżyniera już będę teraz robił. ;) PS. Przypomniało mi się jeszcze jedno, EOF według Kernighana i Ritchiego jest definem wykraczzającym poza zakres char'a, i teoretycznie powinno się ją porównywać jedynie z czymś wielkości int'a (ew. shortem, choć nie wiem jaką wartość dokładnie posiada). Jednak pomimo tego program działa, może to zasługa kompilatora. Sam dopiero niedawno się o tym dowiedziałem, a może Ci się przyda.

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