matematykaszkolna.pl
C Benny: Napisz funkcję o nazwie wykreślanka, której parametrami będą dwa słowa co najwyżej 30−literowe: slowo1 i slowo2, która zwraca 1, jeśli w slowo1 da sie wykreślić niektóre litery, tak aby pozostałe litery(bez zmiany ich kolejności) tworzyły slowo 2 i wraca 0 w przeciwnym wypadku. Np. po wykreśleniu ze słowa INFORMATYKA liter: N, F, O, M, T, Y, A da się otrzymać słowo IRAK. Wskazówka: zauważ, że jeśli potraktujemy słowa jak ciągi, to slowo2 jest podciągiem slowo1.
23 cze 18:43
Saizou : ja bym to zrobił w tablicy i porównywał elementy tablic
23 cze 19:35
jc: Opisz algorytm, a potem zapisz w wymaganym języku (pewnie C, jak poprzednio) −−−−− #include<stdio> int wykreslanka(char slowo1 [ ], char slowo2 [ ] ){ // miejsce na Twoje dzieło } int main(){ printf("%d\n", wykreslanka("informatyka", "irak") ); }
23 cze 19:54
Benny: Udało się. Nie wiedziałem, gdzie mam błąd. W końcu okazało się że w mainie nie deklarowałem długości tablicy
23 cze 19:56
Benny: jc mógłbyś sprawdzić czy czegoś nie brakuje? #include<stdio.h> #include<string.h> #include<conio.h> int wykreslanka(char slowo1[30], char slowo2[30]) { int i=0; int licznik=0; for(i=0; i<strlen(slowo2); i++) { for(int j=0; j<strlen(slowo1); j++) { if(slowo2[i]==slowo1[j]) { licznik ++; break; } } } if(licznik==strlen(slowo2)) return 1; return 0; } main() { char slowo1[30], slowo2[30]; printf("Podaj slowo pierwsze:"); scanf("%s", &slowo1); printf("Podaj slowo drugie:"); scanf("%s", &slowo2); if(wykreslanka(slowo1,slowo2)==1) printf("Slowo drugie jest wykreslanka"); printf("Slowo drugie nie jest wykreslanka"); getch(); }
23 cze 19:57
jc: Drobna uwaga. Nie rozciągj tak tekstu bo trudno się czyta. Oj, coś mi się zdaje, że źle to działa ... (mój program działa, zaraz skomiluję Twój).
23 cze 20:10
jc: To ma być C, czy C++ ? Kompilacja nie powiodła się
23 cze 20:15
jc: slowo jest już adresem, więc npais &slowo jest błędem.
23 cze 20:23
jc: emotka Proponuję cos takiego. Będzisz mógł wielokrotnie wpisywać dane. Wyjdzisz z programu wpisując pojedynczą literę. I nie dopisuje tego getch(). To na pradwę nie potrzebne. Program konsolowy uruchamiasz w konsoli i po problemie! −−−− int main() { char slowo1[30], slowo2[30]; while(1){ printf("Podaj slowo pierwsze:"); scanf("%s", slowo1); if(strlen(slowo1)==1) return 0; printf("Podaj slowo drugie:"); scanf("%s", slowo2); printf("%d\n", wykreslanka(slowo1,slowo2)); } return 0; }
23 cze 20:36
Benny: Dzięki, tylko powiedz czemu moja wersja u mnie działa. No i oczywiście piszę w C.
23 cze 21:18
Benny: No i kiedy mam dawać & a kiedy nie?
23 cze 21:22
jc: Może kompilujesz jako c++ ? Chodzi o drobiazg: for(int i; ; ) Jakiego kompilatora używasz ? & liczba jest adresem zmiennej o nazwie liczba. Aby funkcja scanf() mogła coś umieścić w zmiennej, należy przekazać jej adres zmiennej. Nazwa tablicy sama jest adresem − adresem początku tablicy.
23 cze 21:38
Benny: Używam deva
23 cze 21:55
jc: Pewnie wydajesz polecenie g++ zamiast gcc (wiem, robi to za Ciebie system). Teraz rozumiem, po co Ci getch( ). Po prostu uruchamiasz progrma przyciskiem w systemie dev, a nie poleceniem.
23 cze 22:36
Benny: Ty kompilujesz program i dopiero później odpalasz go przez wiersz poleceń?
23 cze 23:24
jc: Używam Geany. Ostatnio bardzo rzadko zdarza mi się kompilować, Najczęściej używam pythona. Konsola (terminal, wiersz poleceń) pozwala na coś takiego program < dane > wyniki program zamiast z klawiatury czyta z pliku dane, a wynik umieszcza w pliku wyniki. W takiej sytacji dodatkowe pytania zadwane przez program czy też oczekiwanie na przyciśnięcie klawisza przeszkadzają. Tylko kilka razy napisałem program, który sam tworzył pliki (ale za to dużo!).
24 cze 00:08
Benny: Mam teraz napisać program, który wczyta wpisane przez użytkownika slowo1 a następnie wypisze na ekranie wszystkie takie słowa(każde słowo w innym wierszu) ze slownik.txt, które dadzą się otrzymać ze slowo1 poprzez wykreślenie niektórych liter. Trzeba wykorzystać tą funkcję co napisałem powyżej. W tym pliku slownik.txt w każdym wierszu znajduje się jedno słowo.
24 cze 09:25
jc: Zaproponowałbym coś takiego (zmieniasz u siebie tylko main): −−− int main(int argc, char * argv[]){ char slowo[30]; if(argc != 2) return 1; while( scanf("%s", slowo) != EOF ) if(wykreslanka(argv[1], slowo)) printf("%s\n", slowo); return 0; } −−− Uruchamiasz wydając komendę: wyliczanka informatyka < slownik.txt > wyjscie.txt Program wyliczanka umieści w pliku wyjscie.txt te słowa ze słownika.txt, które można uzyskać wykreslając litery w słowie informatyka.
24 cze 10:18
Benny: Właśnie on ma to na ekranie wypisać. Nie rozumiem w ogóle tego programu i maina.
24 cze 10:19
jc: Jak napiszesz wyliczanka informatyka < slownik.tx to wypisze na ekranie. Sprawdź! A potem napisz program, który spyta Cię o słowo, potem o nazwę pliku ze słownikiem, otworzy plik, napisze wynik na ekranie. Będzie to jednak program mniej wygodny w obsłudze. Czy nie pisałeś komend z argumentami? np. gcc wyliczanka.c −o wyliczanka
24 cze 10:31
Benny: Nie wydaje mi się
24 cze 10:39
jc: Co Ci się nie wydaje? Zapewne chciałes mieć coś takiego: −−−−− int main(){ char we[30]; scanf("%s", we); FILE *f; f=fopen("slownik.txt", "r"); while( fscanf("%s", slowo) != EOF) if(wykreslanka(we, slowo)) printf("%s\n", slowo); fclose(f); return 0; }
24 cze 10:41
Benny: co to jest slowo?
24 cze 10:48
jc: A teraz? int main(){ char slowo1[30], slowo2[30]; scanf("%s", slowo1); FILE *f; f=fopen("slownik.txt", "r"); while( fscanf("%s", slowo2) != EOF) if(wykreslanka(slowo1, slowo2)) printf("%s\n", slowo2); fclose(f); return 0; }
24 cze 10:52
Benny: Nie rozumiem tej pętli.
24 cze 10:57
jc: Czytsz słowo. Może się nie udać. Jeśli plik się skończył, wychodzisz z pętli. Jeśli się udało odczytać słowo, to zostanie ono zapamiętane w zmiennej slowo2. Sprawdzasz, czy słowo2 można utworzyć ze słowa1. Jeśli tak, to piszesz słowo2 i przechodzisz do nowej linii. Wracasz na początek pętli.
24 cze 11:21
Benny: No właśnie coś nie chciało działać. Spróbowałem tak, ale po wpisaniu słowa do terminala od razu wyskakuje "skonczylem". char slowo1[30], slowo2[30]; scanf("%s", slowo1); FILE *f; f=fopen("slownik.txt", "r"); while(!feof(f)) { fscanf(f, "%s", slowo2); if(wykreslanka(slowo1, slowo2)==1) printf("%s\n", slowo2); } fclose(f); printf("skonczylem"); getch();
24 cze 11:23
jc: Nie działało, bo nie wpisałem pierwszego argumentu do funkcji fscanf(). Dziwne, że się skompilowało. Nie powinno! Jaką komendę wydajesz w celu kompilacji? Mimo wszystko proponuję pisać tak, jak pisali klasycy C (twórcy!) int main(){ char slowo1[30], slowo2[30]; scanf("%s", slowo1); FILE *f; f=fopen("slownik.txt", "r"); while( fscanf(f, "%s", slowo2) != EOF) if(wykreslanka(slowo1, slowo2)) printf("%s\n", slowo2); fclose(f); return 0; }
24 cze 11:36
jc: A może inaczej: z jakim rozszerzeniem tworzysz pliki?
24 cze 11:59
Benny: cpp
24 cze 12:14
jc: Jeśli chcesz sprawdzać zgodność z C, pisz rozszerzenie c, choć wybór cpp nie jest zły. Najlepiej pisz tak, jak zaproponowano na zajęciach. Sprawdziłem, kompilator c++ też jest zły na brak litery f!
24 cze 12:25
Benny: To co napisałeś powinno działać?
24 cze 12:26
jc: Przecież to to samo, co Ty napisałeś, tylko ja zgodnie z książka piszę while( fscanf(f, "%s", slowo2) != EOF) if(wykreslanka(slowo1, slowo2)) printf("%s\n", slowo2); a Ty rozdzielasz na dwie instukcje while(!feof(f)) { fscanf(f, "%s", slowo2); if(wykreslanka(slowo1, slowo2)==1) printf("%s\n", slowo2); } Poza tym pytasz, czy wykreślanka równa jest jeden. Naturalniejsze jest pytanie, czy udało się wykreślić, czyli bez tego ==1. Lepiej się czyta.
24 cze 12:35
Benny: Tylko coś mi to nie chce działać.
24 cze 12:40
jc: Niemożliwe, oto cały mój program. Sprawdź emotka −−− #include<stdio.h> int wykreslanka(char slowo1[], char slowo2[]){ int i; int j = 0; for(i = 0; slowo2[i]; i++){ while( slowo1[j] && slowo2[i] != slowo1[j]) j++; if( slowo1[j]==0 ) return 0; j ++; } return 1; } int main(){ char slowo1[30], slowo2[30]; scanf("%s", slowo1); FILE *f; f=fopen("slownik.txt", "r"); while( fscanf(f, "%s", slowo2) != EOF) if(wykreslanka(slowo1, slowo2)) printf("%s\n", slowo2); fclose(f); return 0; }
24 cze 13:05
Benny: Ok Twoje działa poprawnie, a moje coś nie do końca.
24 cze 13:24