MeHow Opublikowano 12 Grudnia 2004 Zgłoś Opublikowano 12 Grudnia 2004 Witam, tym razem mam dosyc nie blachy problem. Napisalem sobie program, ktory pozwala nam tworzyc testy angielskiego, sortowac je, mieszac pytania w obrebie testu, no i oczywiscie rozwiazywac je. Problem pojawia sie dopiero w momencie, gdy chce go skompilowac. Kompilacja przebiega zawsze bezblednie, lecz problem pojawia sie pozniej. Pod Borlandem program dziala prawidlowo, natomiast pod gcc, dev program niestety nie pracuje tak jak powinien :( . Problem pojawia sie przy wykonywaniu testu. Problem zobrazuje przy uzyciu przykladu. Jesli np. zadane pytanie to pies , to odpowiedz powinna byc dog, za co dostajemy 1 pkt. W przypadku wszystkich kompilatorow dziala poprawnie. Natomiast powinno byc tak, ze jezeli sa poprawne spolgloski i w dobrej kolejnosci, to powinno sie otrzymywac 0,5pkt . Gdy skompiluje sie program Borlandem, to rzeczywiscie tak jest, jednakze gdy kompilowac bede pod dev albo gcc, to w takim wypadku otrzymuje 0 pkt zamiast 0,5 . W/w wypadku powinno to wygladac tak: pytanie: pies odpowiedz: doooog i powinno byc 0,5 pkt, albo nawet jak napisze odpowiedz: dg to tez powinno byc 0,5 pkt, ale niestety pod dev i gcc cos jest nie tak. Ponizej wklejam kod swojego programu. Prosze o pomoc. [php:1:f70537be0f] #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define ILOSC_PYTAN_W_TESCIE 5 #define MAX_ILOSC_TESTOW 20 struct pytanie_t { char polskie[30]; int ilosc_odpowiednikow; char angielskie[3][30]; }; struct test_t { char nazwa[80]; char stopien_trudnosci[10]; struct pytanie_t pytanie[iLOSC_PYTAN_W_TESCIE]; }; int ile_testow_w_bazie = 0; int find_free( struct test_t[] ); void init_list( struct test_t[] ); int wybor_z_menu( void ); void wprowadz_test( struct test_t[] ); void wyswietl_testy( struct test_t[] ); void usun_test( struct test_t[] ); void sort_nazw( struct test_t*, int, int ); void sort_trud( struct test_t*, int, int ); void sortuj( struct test_t[] ); void mieszaj( struct test_t[], int ); void przeprowadz_test( struct test_t[], int ); float ocen( struct test_t[], int, int, char[] ); int jestsplg( char ); void main( void ) { int choice; int nr; char string[10]; struct test_t test[MAX_ILOSC_TESTOW]; init_list( test ); /* inicjalizacja tablicy struktur */ for(;;) { choice = wybor_z_menu(); switch( choice ) { case 1: wprowadz_test( test ); break; case 2: sortuj( test ); break; case 3: wyswietl_testy( test ); break; case 4: usun_test( test ); break; case 5: { printf("nPodaj numer testu.n"); fgets( string, 9, stdin ); nr = atoi( string ); przeprowadz_test( test, nr ); break; } case 6: exit(0); } } } void wprowadz_test( struct test_t test[] ) { int gdzie, i, t; char c[20]; gdzie = find_free( test ); if( gdzie == -1 ) { printf("Baza jest pelna...n"); return; } printf("nnPodaj nazwe testu:n"); fgets( test[gdzie].nazwa, 24, stdin ); ile_testow_w_bazie++; printf("Podaj stopien trudnosci tego testu:n"); gets( test[gdzie].stopien_trudnosci ); for( i=0; i<ILOSC_PYTAN_W_TESCIE; i++ ) { printf("Pytanie nr %d:n", i+1); fgets( test[gdzie].pytanie.polskie, 29, stdin ); printf("Ile odpowiednikow angielskich ma to slowo?n"); gets( c ); test[gdzie].pytanie.ilosc_odpowiednikow = atoi( c ); //ZROBIC ZABEZPIECZENIE NA ILOSC_ODPOWIEDNIKOW for( t=1; t<=test[gdzie].pytanie.ilosc_odpowiednikow; t++) { printf("Podaj %d odpowiednik:n", t); fgets( test[gdzie].pytanie.angielskie[t-1], 29, stdin ); } } }/* WPROWADZ_TEST */ int find_free( struct test_t test[] ) { int t; for(t=0; test[t].nazwa[0] && t<MAX_ILOSC_TESTOW; ++t); if( t==MAX_ILOSC_TESTOW ) return -1; /* brak wolnych miejsc */ return t; }/* FIND_FREE */ void init_list( struct test_t test[] ) { int t; for(t=0; t<MAX_ILOSC_TESTOW; ++t) test[t].nazwa[0] = '\0'; }/* INIT_LIST */ int wybor_z_menu( void ) { char s[80]; int c; printf("nnn1. Wprowadz nowe dane.n"); printf("2. Sortuj testy.n"); printf("3. Wyswietl dostepne testy.n"); printf("4. Usun test.n"); printf("5. Przeprowadz test.n"); printf("6. Koniec programu.n"); do { printf("nPodaj swoj wybor: "); gets(s); c = atoi(s); } while( c<1 || c>6 ); return c; }/* WYBOR_Z_MENU */ void usun_test( struct test_t test[] ) { int slot; char s[80]; int i = 0; if( ile_testow_w_bazie == 0 ) { printf("nBaza jest pusta...n"); return; } printf("nPodaj numer testu, ktory chcesz usunac:n"); gets(s); slot = atoi(s); if( slot >= 1 && slot <= MAX_ILOSC_TESTOW) { test[slot-1].nazwa[0] = '\0'; if( ile_testow_w_bazie > 0 ) ile_testow_w_bazie--; printf("nUsunieto test o numerze %d.n", slot); } if( ile_testow_w_bazie == 0 ) return; for( i=slot-1; i<MAX_ILOSC_TESTOW-1; i++ ) { if( test[i+1].nazwa[0] == '\0' ) break; test = test[i+1]; } test[ile_testow_w_bazie].nazwa[0] = '\0'; } void wyswietl_testy( struct test_t test[] ) { int i, j; printf("nW bazie dostepne sa nastepujace testy:n"); for( i=0; i<ile_testow_w_bazie; i++ ) { printf("%d. "%s"", i+1, test.nazwa); for( j=0; j<ILOSC_PYTAN_W_TESCIE; j++ ) printf("t%s", test.pytanie[j].polskie ); } } void sortuj( struct test_t test[] ) { char s[20]; int t; printf("n1. Sortuj wedlug nazw testow.n"); printf("2. Sortuj wedlug stopnia trudnosci.n"); do { printf("Wybierz kryterium sortowania:n"); gets( s ); t = atoi( s ); } while( t<1 && t>2 ); if( t==1 ) sort_nazw( test, 0, ile_testow_w_bazie ); else sort_trud( test, 0, ile_testow_w_bazie ); } void sort_nazw( struct test_t tab[], int skad, int dokad ) { int a, b; struct test_t temp; for( a=skad; a<dokad; a++ ) for( b=skad; b<dokad-1; b++ ) if( strcmp( tab.nazwa, tab[b+1].nazwa ) > 0 ) { temp = tab; tab = tab[b+1]; tab[b+1] = temp; } }/* SORT_NAZW */ void sort_trud( struct test_t tab[], int skad, int dokad ) { int a, b; struct test_t temp; for( a=skad; a<dokad; a++ ) for( b=skad; b<dokad-1; b++ ) if( strcmp( tab.stopien_trudnosci, tab[b+1].stopien_trudnosci ) > 0 ) { temp = tab; tab = tab[b+1]; tab[b+1] = temp; } /* for( a=skad; a<dokad; a++ ) if( !strcmp(tab[a], "latwy") || !strcmp(tab[a], "łatwy") ) */ } void mieszaj( struct test_t test[], int numer ) { int i, index; struct pytanie_t temp; int dz = RAND_MAX/ILOSC_PYTAN_W_TESCIE + 1; for( i=0; i < ILOSC_PYTAN_W_TESCIE; i++ ) { index = rand()/dz; temp = test[numer].pytanie; test[numer].pytanie = test[numer].pytanie[index]; test[numer].pytanie[index] = temp; } } void przeprowadz_test( struct test_t test[], int numer ) { int i; char odp[30]; float l_pkt = 0; float pkt = 0; mieszaj( test, numer-1 ); printf("n"); for(i=0; i<ILOSC_PYTAN_W_TESCIE; i++) { printf("%sn", test[numer-1].pytanie.polskie); printf("Twoja odpowiedz: "); fgets( odp, 29, stdin ); pkt = ocen( test, numer-1, i, odp ); printf("tt%.1f pktn", pkt); l_pkt += pkt; } printf("nnZdobyles %.1f punktow.n", l_pkt); } float ocen( struct test_t test[], int numer, int pyt, char odp[] ) { int i, j, k, n; char lan1[30], lan2[30]; for(i = 0; i<test[numer].pytanie[pyt].ilosc_odpowiednikow; i++) if( !strcmp(test[numer].pytanie[pyt].angielskie, odp) ) return 1; n = strlen( odp ); for(i=0, j=0; i<n; i++ ) if( jestsplg( odp ) ) lan1[j++] = odp; for(i = 0; i<test[numer].pytanie[pyt].ilosc_odpowiednikow; i++) { n = strlen( test[numer].pytanie[pyt].angielskie ); for( j=0, k=0; j<n; j++) if( jestsplg( test[numer].pytanie[pyt].angielskie[j] ) ) lan2[k++] = test[numer].pytanie[pyt].angielskie[j]; if( !strcmp(lan1, lan2) ) return 0.5; } return 0; } int jestsplg( char c ) { if( isalpha( c ) && c != 'a' && c != 'e' && c != 'i' && c != 'o' && c != 'u' && c != 'y' ) return 1; else return 0; } [/php:1:f70537be0f] Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
spicum Opublikowano 12 Grudnia 2004 Zgłoś Opublikowano 12 Grudnia 2004 Problem lezy w tym ze czesc kompilatorow inicjalizuje tablice czy to charow czy tez innych typow prostych. gcc nie ma tego w zwyczaju. dopisz w funkcji ocen inicjalizacje tablic lan1 i lan2 [php:1:c197ee50dd] float ocen( struct test_t test[], int numer, int pyt, char odp[] ) { int i, j, k, n; char lan1[30], lan2[30]; for (i = 0; i< 30; i++) { lan1 = '\0'; lan2 = '\0'; } ... } [/php:1:c197ee50dd] Jesli nie dokonasz inicjalizacji tych tablic - lub po prostu nie zakonczysz wpisywanego w tablice stringa znakiem '\0' to strcmp pogubi sie jesli chodzi o dlugosci stringow i przeczyta wszystko z losowym smietnikiem pamieci wpisanym dalej. Sprawdzilem na gcc dziala. Co do Borlanda - pewnie automtycznie wypelnia przy inicjalizacji tablice charow znakami konca '\0'; Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
yasin Opublikowano 12 Grudnia 2004 Zgłoś Opublikowano 12 Grudnia 2004 nie chce mi sie wglebiac w kod, ale imho wyglada mi na to ze zle opererujesz na pamieci, byc moze borland maskuje w jakis sposob twoje bledy, a dev trzyma sie ANSI Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
MeHow Opublikowano 12 Grudnia 2004 Zgłoś Opublikowano 12 Grudnia 2004 spcium. Probowalem na gcc z Mandrake 10 i nie dzialalo, sprobowalem na gcc pod Solarisem i zadzialalo. Zaraz sprobuje wykonac to co ty sugerujesz (tylko zainstaluje Win2000 i Slacka ;] ) ---EDIT--- spcium, potwierdzam, dziala. Zapomnialem o tym, ze jesli inicjalizuje tablice wewnatrz funkcji, to zostaje ona wypelniona losowymi smieciami z pamieci. :) WIELKIE DZIEKI ZA POMOC :) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
spicum Opublikowano 12 Grudnia 2004 Zgłoś Opublikowano 12 Grudnia 2004 A to Ciekawe. Testowalem na Slolarisie 5.8 z gcc 2.95. i dopiero po inicjalizacji tych tablic zadzialalo... Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
MeHow Opublikowano 12 Grudnia 2004 Zgłoś Opublikowano 12 Grudnia 2004 Ja testowalem na solarisie, ktorego mamy na laborkach z PRI na PW i zadzialalo bez zmian. W sumie ciekawa sprawa :). Wazne, ze teraz nawet pod dev wszystko pieknie dziala :) Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...