Čer
20
20
Základy programování (IZP) – Projekt č. 3 a 4
Třetí projekt se týkal práce s maticemi, cílem posledního projektu byl program, který filtroval vstupní textový soubor.
Hodnocení:
3. projekt – 9/10
4. projekt – 7.5/8
Je zakázáno kopírovat tyto zdrojové kódy! Veškeré projekty procházejí kontrolou na plagiátorství, takže se nepokoušejte použít mé kódy a to ani tak, že přepíšete názvy proměnných, nepomůže to. Výsledkem opisování je předvolání před komisi a většinou také odebrání zápočtu, takže vzhledem k tomu, že jsem nezpochybnitelným autorem následujících kódů, uškodíte pouze sami sobě.
Projekt č. 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 | /* Projekt c.3 - Maticove operace * Autor: Milan Seitler, xseitl01@fit.vutbr.cz * Skupina: 36 (1BIB) * Datum: 2010/12/5 * Nazev souboru: proj3.c * Popis programu: program provadi operace s vektory a maticemi - soucet a skalarni soucin vektoru, maticove vyrazy A*B a A*B*A, dale pak funkci eight, ktera hleda, zda se zadany vektor nachazi v zadane matici. Posledni funkci je bubbles, tato funkce hleda v zadane matici skupiny nul, ktere spolu souviseji ve svem ctyrokoli. Tyto skupiny se nazyvaji bubliny a program hleda jejich pocet v matici. Program lze spustit s temito parametry -h - napoveda --test data.txt - slouzi pouze ke kontrole vstupnich dat, spravne formatovana data vypise na standardni vstup --vadd a.txt b.txt - soucet dvou zadanych vektoru --vscal a.txt b.txt - skalarni soucin dvou zadanych vektoru --mmult A.txt B.txt - soucin dvou zadanych matic --mexpr A.txt B.txt - vypocita maticovy vyraz A*B*A --eight v.txt M.txt - osmismerka, vyhleda vektor V v matici M --bubbles M.txt - hleda "bubliny" v zadane matici */ #include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // kody chyb #define K_OK 0 //bez chyb #define K_CHYBNY_PARAMETR 1 // chybny parametr prikazove radky #define K_CHYBNY_VSTUP 2 // chybny vstup #define K_NEDOSTATEK_PAMETI 3 // nedostatek pameti #define K_SOUBOR_OTEVRIT 4 // chyba pri otevirani souboru #define K_SOUBOR_ZAVRIT 5 // chyba pri zavirani souboru // urcime si kody jednotlivych funkci, podle kterych budeme volat #define HELP 0 // napoveda #define TEST 1 // testovaci funkce #define VADD 2 // soucet vektoru #define VSCAL 3 // skalarni soucin vektoru #define MMULT 4 // A*B (matice) #define MEXPR 5 // A*B*A (matice) #define EIGHT 6 // osmismerka #define BUBBLES 7 //2D bubliny #define START 0 // uvodni pozice osmismerky // navratove hodnoty funkci #define TRUE 1 #define FALSE 0 // struktura slouzi k nacteni a osetreni parametru ve funkci nacti_parametry typedef struct parametry { int spust; // do promenne spust ukladame kod funkce, kterou chceme spustit, ten nacteme z prikazove radky char *s1, *s2; // do s1 a s2 ukladame soubory, se kterymi budeme pracovat } Tparam; typedef struct matice { // struktura pro matice int radky; int sloupce; int *cisla; } Tmatice; typedef struct vektor { //struktura pro vektory int pocet; int *cisla; } Tvektor; typedef struct vektor_matic { // struktura pro vektor matic int pocet; int radky; int sloupce; int *cisla; } Tvektor_m; typedef struct hlavicka_souboru { // do teto struktury se ukladaji informace o typu objektu v souboru int typ; int pocet; int radky; int sloupce; } Thlavicka; //----------------------------------------------------------------------------------------------- // prototypy funkci ----------------------------------------------------------------------------- void nacti_parametry(int argc, char *argv[], Tparam *x); //nacteni parametru z prikazove radky int vypis_chybu(int kod); // funkce vypisu chybu na stderr dle zadaneho kodu void napoveda(void); FILE *otevri_soubor(char *nazev); void zavri_soubor(FILE *soubor); // tri funkce pro alokaci pameti int alokuj_matici(int r, int s, Tmatice *m); int alokuj_vektor(int p, Tvektor *v); int alokuj_vektor_m(int p, int r, int s, Tvektor_m *vm); // tri funkce pro uvolneni pameti void uvolni_matici(Tmatice m); void uvolni_vektor(Tvektor v); void uvolni_vektor_matic(Tvektor_m vm); // tri funkce pro nacteni objektu ze souboru int nacti_vektor(Tvektor *v, FILE *soubor); int nacti_matici(Tmatice *m, FILE *soubor); int nacti_vektor_m(Tvektor_m *vm, FILE *soubor); // tri funkce pro vypsani void vypis_vektor(Tvektor *v); void vypis_matici(Tmatice *m); void vypis_matici(Tmatice *m); int nacti_hlavicku(Thlavicka *m, FILE *soubor); // nacte hlavicku objektu - typ, pocet radku, ... // samotne vypocetni funkce void test(FILE *soubor); int vadd(Tvektor vektor1, Tvektor *vektor2); int vscal(Tvektor vektor1, Tvektor vektor2); int mmult(Tmatice matice1, Tmatice matice2, Tmatice *matice3); int eight(Tvektor *vektor, Tmatice *matice); int bubbles(Tmatice matice); Tmatice vynasob_matice(Tmatice m1, Tmatice m2, Tmatice m3); // samotne nasobeni dvou matic, vysledek se uklada do matice m3 int preved_index(int r, int s, Tmatice m1); // pouzivam 1D pole, tato funkce prevadi index prvku na souradnice radky x sloupce void hledej_bubliny(int x, int y, Tmatice *matice); // rekurzivni funkce pro hledani nul v okoli zadane souradnice // funkce pro pripraveni vektoru a matic - alokace, nacteni void priprav_vektory(Tvektor *vektor1, Tvektor *vektor2, FILE *soubor1, FILE *soubor2); void priprav_matice(Tmatice *matice1, Tmatice *matice2, Tmatice *matice3, FILE *soubor1, FILE *soubor2); // prototypy funkci ----------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { Tparam param; // vytvorime strukturu pro parametry // vytvorime struktury pro jednotlive typy objekty Thlavicka hlavicka1, hlavicka2; Tmatice matice1, matice2, matice3; Tvektor vektor1, vektor2; int vysledek = 0, ok = 0; // promenne pro ukladani vysledku a navratovych hodnot funkci FILE *soubor1 = NULL, *soubor2 = NULL; param.s1 = ""; // "vynuluju" oba nazvy souboru param.s2 = ""; nacti_parametry(argc, argv, ¶m); // nactene parametry ukladame do struktury // otevru soubor s danym nazvem, pokud existuje, vrati mi to ukazatel if(param.spust != HELP) { soubor1 = otevri_soubor(param.s1); if(soubor1 == NULL) { // pokud nastane pri otevirani chyba, oznamime uzivateli a ukoncime program zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_SOUBOR_OTEVRIT); } } if(param.spust != TEST && param.spust != BUBBLES && param.spust != HELP) { // pokud nespoustim test nebo bubliny, nactu druhy soubor soubor2 = otevri_soubor(param.s2); if(soubor2 == NULL) { // pokud nastane pri otevirani chyba, oznamime uzivateli a ukoncime program zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_SOUBOR_OTEVRIT); } } switch(param.spust) { // testujeme, kterou funkci mame spustit case HELP: napoveda(); break; case TEST: test(soubor1); break; case VADD: priprav_vektory(&vektor1, &vektor2, soubor1, soubor2); // alokace a nacteni vektoru ok = vadd(vektor1, &vektor2); if(ok == FALSE) { // pokud nam vypocetni funkce vrati FALSE, vypiseme na standardni vystup printf("\nfalse\n"); } else { vypis_vektor(&vektor2); } uvolni_vektor(vektor1); uvolni_vektor(vektor2); break; case VSCAL: priprav_vektory(&vektor1, &vektor2, soubor1, soubor2); // alokace a nacteni vektoru vysledek = vscal(vektor1, vektor2); if(vysledek >= 0) { // pokud nam vypocetni funkce vrati FALSE, vypiseme na standardni vystup printf("\n%d\n", vysledek); } else { printf("\nfalse\n"); } uvolni_vektor(vektor1); uvolni_vektor(vektor2); break; case MMULT: priprav_matice(&matice1, &matice2, &matice3, soubor1, soubor2); // alokace a nacteni matic ok = mmult(matice1, matice2, &matice3); if(ok == FALSE) { // pokud nam vypocetni funkce vrati FALSE, vypiseme na standardni vystup printf("\nfalse\n"); } else { vypis_matici(&matice3); } uvolni_matici(matice1); uvolni_matici(matice2); uvolni_matici(matice3); break; case MEXPR: priprav_matice(&matice1, &matice2, &matice3, soubor1, soubor2); // alokace a nacteni matic ok = mmult(matice1, matice2, &matice3); if(ok == FALSE) { // pokud nam vypocetni funkce vrati FALSE, vypiseme na standardni vystup printf("\nfalse\n"); uvolni_matici(matice1); uvolni_matici(matice2); uvolni_matici(matice3); zavri_soubor(soubor1); zavri_soubor(soubor2); return K_OK; } uvolni_matici(matice2); // uvolni druhou matici, kterou pouzijeme k ulozeni druheho vypoctu if(alokuj_matici(matice3.radky, matice1.sloupce, &matice2) == K_NEDOSTATEK_PAMETI) { uvolni_matici(matice1); uvolni_matici(matice2); uvolni_matici(matice3); zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_NEDOSTATEK_PAMETI); } ok = mmult(matice3, matice1, &matice2); if(ok == FALSE) { // pokud nam vypocetni funkce vrati FALSE, vypiseme na standardni vystup printf("\nfalse\n"); } else { vypis_matici(&matice2); } uvolni_matici(matice1); uvolni_matici(matice2); uvolni_matici(matice3); break; case EIGHT: if(nacti_hlavicku(&hlavicka1, soubor1) == K_CHYBNY_VSTUP || nacti_hlavicku(&hlavicka2, soubor2) == K_CHYBNY_VSTUP) { zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_NEDOSTATEK_PAMETI); } // nacte hlavicku souboru, pokud nastane chyba, vypiseme chybove hlaseni a ukoncime program if(alokuj_vektor(hlavicka1.pocet, &vektor1) == K_NEDOSTATEK_PAMETI || alokuj_matici(hlavicka2.radky, hlavicka2.sloupce, &matice1) == K_NEDOSTATEK_PAMETI){ uvolni_vektor(vektor1); uvolni_matici(matice1); zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_NEDOSTATEK_PAMETI); } // alokuje pamet pro vektor a matici, pri chybe uvolnime pamet a soubory, vypiseme chybove hlaseni a ukoncime program if(nacti_vektor(&vektor1, soubor1) == K_CHYBNY_VSTUP || nacti_matici(&matice1, soubor2) == K_CHYBNY_VSTUP) { uvolni_vektor(vektor1); uvolni_matici(matice1); zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_CHYBNY_VSTUP); } // nacteni dat do alokovaneho vektoru a matice, pri chybe vypiseme chybove hlaseni, vse uvolnime, zavreme a ukoncime program vysledek = eight(&vektor1, &matice1); printf("\n%d\n", vysledek); uvolni_vektor(vektor1); uvolni_matici(matice1); break; case BUBBLES: if(nacti_hlavicku(&hlavicka1, soubor1) == K_CHYBNY_VSTUP) { zavri_soubor(soubor1); exit(K_CHYBNY_VSTUP); } // nacte hlavicku souboru, pokud nastane chyba, vypiseme chybove hlaseni a ukoncime program if(hlavicka1.typ != 2) { zavri_soubor(soubor1); exit(vypis_chybu(K_CHYBNY_VSTUP)); } // pokud uzivatel zada neco jineho nez matici, vypiseme chybove hlaseni a ukoncime program if(alokuj_matici(hlavicka1.radky, hlavicka1.sloupce, &matice1) == K_NEDOSTATEK_PAMETI) { zavri_soubor(soubor1); exit(K_NEDOSTATEK_PAMETI); } // alokujeme misto pro matici a zaroven kontrolujeme vysledek alokace if(nacti_matici(&matice1, soubor1) == K_CHYBNY_VSTUP) { uvolni_matici(matice1); zavri_soubor(soubor1); exit(K_CHYBNY_VSTUP); } // nacteni dat do matice + kontrola uspesnosti nacteni vysledek = bubbles(matice1); printf("\n%d\n\n", vysledek); uvolni_matici(matice1); default: break; } zavri_soubor(soubor1); //zavru soubory zavri_soubor(soubor2); return EXIT_SUCCESS; } void nacti_parametry(int argc, char *argv[], Tparam *x) { if(argc == 4) { // podle poctu argumentu porovnavame retezec s moznymi funkcemi if(strcmp("--vadd", argv[1]) == 0) { x->spust = VADD; } else if(strcmp("--vscal", argv[1]) == 0) { x->spust = VSCAL; } else if(strcmp("--mmult", argv[1]) == 0) { x->spust = MMULT; } else if(strcmp("--mexpr", argv[1]) == 0) { x->spust = MEXPR; } else if(strcmp("--eight", argv[1]) == 0) { x->spust = EIGHT; } else { vypis_chybu(K_CHYBNY_PARAMETR); exit(K_CHYBNY_PARAMETR); } x->s1 = argv[2]; // nactu nazvy souboru x->s2 = argv[3]; } else if(argc == 3) { if(strcmp("--test", argv[1]) == 0) { x->spust = TEST; x->s1 = argv[2]; } else if(strcmp("--bubbles", argv[1]) == 0) { x->spust = BUBBLES; x->s1 = argv[2]; } else { vypis_chybu(K_CHYBNY_PARAMETR); exit(K_CHYBNY_PARAMETR); } } else if(argc == 2) { if(strcmp("-h", argv[1]) == 0){ x->spust = HELP; } else { vypis_chybu(K_CHYBNY_PARAMETR); exit(K_CHYBNY_PARAMETR); } } else { vypis_chybu(K_CHYBNY_PARAMETR); exit(K_CHYBNY_PARAMETR); } } // pokud jsou parametry neplatne, vypise se chybove hlaseni a program se ukonci int vypis_chybu(int kod) // podle obdrzeneho chyboveho kodu vypiseme chybove hlaseni na stderr a ukoncime program { switch(kod) { case 1: fprintf(stderr, "\n\nChybny parametr prikazove radky! Program bude ukoncen. \n\n"); break; case 2: fprintf(stderr, "\n\nChybny znak na vstupu! Program bude ukoncen. \n\n"); break; case 3: fprintf(stderr, "\n\nNastala chyba pri rezervovani pameti! Program bude ukoncen. \n\n"); break; case 4: fprintf(stderr, "\n\nNastala chyba pri otevirani souboru! Pravdepodobne se pokousite otevrit neexistujici soubor. Program bude ukoncen. \n\n"); break; case 5: fprintf(stderr, "\n\nNastala chyba pri zavirani souboru! Program bude ukoncen. \n\n"); break; default: break; } return kod; } FILE *otevri_soubor(char *nazev) // otevre soubor s nazvem *nazev { FILE *soubor = NULL; // vytvorim si pomocny ukazatal na soubor soubor = fopen(nazev, "r"); if(soubor == NULL) { // chyba pri otvirani -> vypise chybove hlaseni a konec vypis_chybu(K_SOUBOR_OTEVRIT); } return soubor; // vratim ukazatel na soubor } void zavri_soubor(FILE *soubor) // zavru soubor, na ktery ukazuje ukazatel *soubor { if(soubor != NULL) { // kdyz ukazatel na nic neukazuje, tak neni co zavrit fclose(soubor); // chyba pri zavirani -> chybove hlaseni a konec } } int alokuj_vektor(int p, Tvektor *v) { int chyba = K_OK; // ulozim parametry do struktury v->pocet = p; v->cisla = malloc(p * sizeof(int)); // alokuje 1D pole if(v->cisla == NULL) { // pokud dojde k chybe vratim 1 a uvolnim v nadrazene funkci vsechny alokace } return chyba; } int alokuj_matici(int r, int s, Tmatice *m) { int chyba = K_OK; // ulozim parametry do struktury m->radky = r; m->sloupce = s; m->cisla = malloc(r*s*sizeof(int)); // alokuje 1D pole if(m->cisla == NULL) { chyba = vypis_chybu(K_NEDOSTATEK_PAMETI); } return chyba; } int alokuj_vektor_m(int p, int r, int s, Tvektor_m *vm) { int chyba = K_OK; // ulozim parametry do struktury vm->pocet = p; vm->radky = r; vm->sloupce = s; vm->cisla = malloc(r*s*sizeof(int)*p); if(vm->cisla == NULL) { chyba = vypis_chybu(K_NEDOSTATEK_PAMETI); // pokud dojde k chybe, preda funkce chybovy kod do nadrazene funkce } else { chyba = K_OK; } return chyba; } void uvolni_matici(Tmatice m) { free(m.cisla); m.cisla = NULL; } void uvolni_vektor(Tvektor v) { free(v.cisla); v.cisla = NULL; } void uvolni_vektor_matic(Tvektor_m vm) { free(vm.cisla); vm.cisla = NULL; } int nacti_vektor(Tvektor *v, FILE *soubor) { int pom = 0, chyba = K_OK; for(int i = 0; i < v->pocet; i++) { if((pom = (fscanf(soubor, "%d", &v->cisla[i]))) == EOF || pom != 1 || errno == ERANGE) { // kontrola chybneho vstupu (preteceni INT, neplatne znaky,..) chyba = vypis_chybu(K_CHYBNY_VSTUP); break; } else { chyba = K_OK; } } if((pom = fscanf(soubor, "%d", &v->cisla[0])) != EOF && chyba == K_OK){ // testujeme, zda nejsou na vstupu dalsi znaky -> chybove hlaseni + konec programu chyba = vypis_chybu(K_CHYBNY_VSTUP); } return chyba; } int nacti_matici(Tmatice *m, FILE *soubor) { int pom = 0; // sem se ulozi vysledek nacteni int delka = m->radky * m->sloupce; // spocitame pocet znaku v matici int chyba = K_OK; for(int i = 0; i < delka; i++) { if((pom = (fscanf(soubor, "%d", &m->cisla[i]))) == EOF || pom != 1 || errno == ERANGE) { // kontrola chybneho vstupu (preteceni INT, neplatne znaky,..) chyba = vypis_chybu(K_CHYBNY_VSTUP); break; } else { chyba = K_OK; } } if((pom = fscanf(soubor, "%d", &m->cisla[0])) != EOF && chyba == K_OK){ // testujeme, zda nejsou na vstupu dalsi znaky -> chybove hlaseni + konec programu chyba = vypis_chybu(K_CHYBNY_VSTUP); } return chyba; } int nacti_vektor_m(Tvektor_m *vm, FILE *soubor) { int pom = 0; // sem se ulozi vysledek nacteni int delka = vm->radky * vm->sloupce * vm->pocet; // spocitame pocet znaku ve vektoru matic int chyba = K_OK; for(int i = 0; i < delka; i++) { if((pom = (fscanf(soubor, "%d", &vm->cisla[i]))) == EOF || pom != 1 || errno == ERANGE) { // kontrola chybneho vstupu (preteceni INT, neplatne znaky,..) chyba = vypis_chybu(K_CHYBNY_VSTUP); break; } else { chyba = K_OK; } } if((pom = fscanf(soubor, "%d", &vm->cisla[0])) != EOF && chyba == K_OK){ // testujeme, zda nejsou na vstupu dalsi znaky -> chybove hlaseni + konec programu chyba = vypis_chybu(K_CHYBNY_VSTUP); } return chyba; } void vypis_vektor(Tvektor *v) { int i = 0; printf("1\n"); // vypiseme hlavicku vektoru printf("%d\n\n", v->pocet); for(i = 0; i < v->pocet; i++) { // a jeho prvky printf("%d ", v->cisla[i]); } printf("\n"); } void vypis_matici(Tmatice *m) { int i = 0; printf("2\n"); // vypiseme hlavicku matice printf("%d %d\n\n", m->radky, m->sloupce); for(i = 0; i < (m->radky * m->sloupce); i++) { // a jeji prvky if(i % m->sloupce == 0) { // pokud jsem na novem radku matice, odradkuju printf("\n"); } printf("%d ", m->cisla[i]); } printf("\n"); } void vypis_vektor_m(Tvektor_m *vm) { int i = 0; printf("3\n"); // vypiseme hlavicku vektoru matic printf("%d %d %d\n", vm->pocet, vm->radky, vm->sloupce); for(i = 0; i < (vm->radky * vm->sloupce * vm->pocet); i++) { // a jeho prvky if(i % (vm->radky * vm->sloupce) == 0) { // pokud zacinam vypisovat novou matici, udelam prazdny radek printf("\n\n"); } else if(i % vm->sloupce == 0) { // pokud jsem na novem radku matice, odradkuju printf("\n"); } printf("%d ", vm->cisla[i]); } printf("\n"); } int nacti_hlavicku(Thlavicka *h, FILE *soubor) { int pom = 0, chyba = K_OK; if(((pom = fscanf(soubor,"%d", &h->typ)) != 1 || pom == EOF) || (h->typ != 1 && h->typ != 2 && h->typ != 3)) { // pokud je na vstupu spatny znak, ukoncime program a vypiseme chybove hlaseni vypis_chybu(K_CHYBNY_VSTUP); chyba = K_CHYBNY_VSTUP; } switch(h->typ) { // podle typu vstupnich dat nacteme udaje o matici, soucasne osetrujeme rozsah vstupnich hodnot a nepovolene znaky case 1: if((pom = fscanf(soubor, "%d", &h->pocet)) != 1 || pom == EOF || h->pocet < 1) { chyba = vypis_chybu(K_CHYBNY_VSTUP); } break; case 2: if((pom = fscanf(soubor, "%d %d", &h->radky, &h->sloupce)) != 2 || pom == EOF || h->radky < 1 || h->sloupce < 1){ chyba = vypis_chybu(K_CHYBNY_VSTUP); } break; case 3: // pokud je na vstupu spatny znak, ukoncime program a vypiseme chybove hlaseni if((pom = fscanf(soubor, "%d %d %d", &h->pocet, &h->radky, &h->sloupce)) != 3 || pom == EOF || h->pocet <1 || h->radky < 1 || h->sloupce < 1) { chyba = vypis_chybu(K_CHYBNY_VSTUP); } break; default: break; } return chyba; } void test(FILE *soubor) { Thlavicka hlavicka; // vytvorim si rucne tri objekty Tvektor vektor; Tmatice matice; Tvektor_m vektor_m; if(nacti_hlavicku(&hlavicka, soubor) == K_CHYBNY_VSTUP) { // nacte hlavicku souboru zavri_soubor(soubor); exit(K_CHYBNY_VSTUP); } if(hlavicka.typ == 1) { // podle typu vstupnich dat alokuje prislusnou strukturu if(alokuj_vektor(hlavicka.pocet, &vektor) == K_NEDOSTATEK_PAMETI){ uvolni_vektor(vektor); zavri_soubor(soubor); exit(K_NEDOSTATEK_PAMETI); } // nacte vektor ze souboru if(nacti_vektor(&vektor, soubor) == K_CHYBNY_VSTUP) { uvolni_vektor(vektor); zavri_soubor(soubor); exit(K_CHYBNY_VSTUP); } vypis_vektor(&vektor); uvolni_vektor(vektor); } else if(hlavicka.typ == 2) { if(alokuj_matici(hlavicka.radky, hlavicka.sloupce, &matice) == K_NEDOSTATEK_PAMETI){ uvolni_matici(matice); zavri_soubor(soubor); exit(K_NEDOSTATEK_PAMETI); } // nacte matici ze souboru if(nacti_matici(&matice, soubor) == K_CHYBNY_VSTUP) { uvolni_matici(matice); zavri_soubor(soubor); exit(K_CHYBNY_VSTUP); } vypis_matici(&matice); uvolni_matici(matice); } else if(hlavicka.typ == 3) { if(alokuj_vektor_m(hlavicka.pocet, hlavicka.radky, hlavicka.sloupce, &vektor_m) == K_NEDOSTATEK_PAMETI){ uvolni_vektor_matic(vektor_m); zavri_soubor(soubor); exit(K_NEDOSTATEK_PAMETI); } // nacte vektor matic if(nacti_vektor_m(&vektor_m, soubor) == K_CHYBNY_VSTUP) { uvolni_vektor_matic(vektor_m); zavri_soubor(soubor); exit(K_CHYBNY_VSTUP); } vypis_vektor_m(&vektor_m); uvolni_vektor_matic(vektor_m); } else { vypis_chybu(K_CHYBNY_VSTUP); } } int vadd(Tvektor vektor1, Tvektor *vektor2) { int i = 0, ok = FALSE; if(vektor1.pocet == vektor2->pocet) { for(i = 0; i < vektor1.pocet; i++) { // secita jednotlive prvky vektoru vektor2->cisla[i] = vektor1.cisla[i] + vektor2->cisla[i]; } ok = TRUE; } else { ok = FALSE; } // vracime vysledek operace, v poradku - TRUE, nelze provest - FALSE return ok; } int vscal(Tvektor vektor1, Tvektor vektor2) { int i = 0, vysledek = 0; if(vektor1.pocet == vektor2.pocet) { for(i = 0; i < vektor1.pocet; i++) { // nasobi jednotlive prvky vysledek += vektor1.cisla[i] * vektor2.cisla[i]; } } else { vysledek = -1; // pokud nelze nasobit, vratime -1, pokud ano vratime vysledek nasobeni } return vysledek; } int mmult(Tmatice matice1, Tmatice matice2, Tmatice *matice3) { int ok = FALSE; if(matice1.sloupce == matice2.radky) { // testujeme, zda matice vyhovuji matematicke definici *matice3 = vynasob_matice(matice1, matice2, *matice3); // provedeme samotne nasobeni ok = TRUE; } else { ok = FALSE; } // vracime zda bylo mozne matice nasobit ci ne return ok; } int eight(Tvektor *vektor, Tmatice *matice) { int x = 0, y = 0, pocet = 1; int stav = FALSE, konec = FALSE; for(x = 0; x < matice->radky; x++) { // prochazime radky for(y = 0; y < matice->sloupce; y++) { // prochazime sloupce if(matice->cisla[preved_index(x, y, *matice)] == vektor->cisla[START]) { // pokud se prvek rovna prvnimu prvku vektoru, zacneme hledat // jednotlive cykly prochazi vsechny smery, zda v nich nelezi pozadovany vektor, k pohybu pouzivame hodnotu "pocet" for(pocet = 1; pocet < vektor->pocet; pocet++) { if(x - pocet >= 0) { // pohyb na sever if(matice->cisla[preved_index((x - pocet), y, *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; // pokud najdeme cely vektor, hodnota konec se nastavi na true, cimz preskocime ostatni cykly } else { stav = FALSE; break; } } else { break; } } for(pocet = 1; pocet < vektor->pocet; pocet++) { if(x - pocet >= 0 && y + pocet < matice->sloupce && konec == FALSE) { // pohyb na severovychod if(matice->cisla[preved_index((x - pocet), (y + pocet), *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; } else { stav = FALSE; break; } } else { break; } } for(pocet = 1; pocet < vektor->pocet; pocet++) { if(y + pocet < matice->sloupce && konec == FALSE) { // pohyb na vychod if(matice->cisla[preved_index(x, (y + pocet), *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; } else { stav = FALSE; break; } } else { break; } } for(pocet = 1; pocet < vektor->pocet; pocet++) { if(x + pocet < matice->radky && y + pocet < matice->sloupce && konec == FALSE) { // pohyb na jihovychod if(matice->cisla[preved_index((x + pocet), (y + pocet), *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; } else { stav = FALSE; break; } } else { break; } } for(pocet = 1; pocet < vektor->pocet; pocet++) { if(x + pocet < matice->radky && konec == FALSE) { // pohyb na jih if(matice->cisla[preved_index((x + pocet), y, *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; } else { stav = FALSE; break; } } else { break; } } for(pocet = 1; pocet < vektor->pocet; pocet++) { if(x + pocet < matice->radky && y - pocet >= 0 && konec == FALSE) { // pohyb na jihozapad if(matice->cisla[preved_index((x + pocet), (y - pocet), *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; } else { stav = FALSE; break; } } else { break; } } for(pocet = 1; pocet < vektor->pocet; pocet++) { if(y - pocet >= 0 && konec == FALSE) { // pohyb na zapad if(matice->cisla[preved_index(x , (y - pocet), *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; } else { stav = FALSE; break; } } else { break; } } for(pocet = 1; pocet < vektor->pocet; pocet++) { if(x - pocet >= 0 && y - pocet >= 0 && konec == FALSE) { // pohyb na severozapad if(matice->cisla[preved_index((x - pocet) , (y - pocet), *matice)] == vektor->cisla[pocet]) { stav = TRUE; if(pocet + 1 == vektor->pocet) konec = TRUE; } else { stav = FALSE; break; } } else { break; } } if(vektor->pocet == 1) { // pokud tvori vektor pouze jeden prvek, nasli jsme jej, vracime true return TRUE; } if(konec == TRUE && stav == TRUE) { // pokud jsme dosli na konec a stav je true, vratime true return TRUE; } else { stav = FALSE; } } } } return stav; } int bubbles(Tmatice matice) { int x = 0, y = 0, pocet = 0; for(x = 0; x < matice.radky; x++) { // pohyb po radcich for(y = 0; y < matice.sloupce; y++) { // pohyb po sloupcich if(matice.cisla[preved_index(x, y, matice)] == 0) { // pokud jsme narazili na nulu, prohledame okoli pomoci rekurzivni funkce hledej_bubliny hledej_bubliny(x, y, &matice); pocet++; // navysime pocet bublin } } } return pocet; } Tmatice vynasob_matice(Tmatice m1, Tmatice m2, Tmatice m3) { int x = 0, y = 0; // pohyb ve vysledne matici int i = 0; // pohyb pri nasobeni for(x = 0; x < m3.radky; x++) { for(y = 0; y < m2.sloupce; y++) { m3.cisla[preved_index(x, y, m3)] = 0; for(i = 0; i < m1.sloupce; i++) { m3.cisla[preved_index(x, y, m2)] += (m1.cisla[(preved_index(x, i, m1))] * m2.cisla[preved_index(i, y, m2)]); // pronasobime vsechny radky a sloupce } } } return m3; } int preved_index(int r, int s, Tmatice m) { return(m.sloupce * r + s); } void napoveda(void) { printf("\n\n" "Maticove operace\n" "Autor: Milan Seitler\n" "\n" "Spusteni programu: ./proj3 -h | --test data.txt| --vadd a.txt b.txt | --vscal a.txt b.txt | --mmult A.txt B.txt | --mexpr A.txt B.txt |" " --eight v.txt M.txt | --bubbles M.txt" "\n\n" "-h - napoveda\n" "--test - kontrolni funkce, spravne formatovany vstup vypise na standardni vystup\n" "--vadd - soucet vektoru\n" "--vscal - skalarni soucin vektoru\n" "--mmult - nasobeni matic\n" "--mexpr - vypocita maticovy vyraz A*B*A\n" "--eight - v matici M hleda vektor V\n" "--bubbles - v matici M hleda bubliny - skupiny nul\n\n" "Program nacita vstupni data ze souboru urcenych parametrem. Program tato data kontroluje " " a pripadne chyby oznami uzivateli na chybovy vystup.\n\n"); } void priprav_vektory(Tvektor *vektor1, Tvektor *vektor2, FILE *soubor1, FILE *soubor2) { Thlavicka hlavicka1, hlavicka2; if(nacti_hlavicku(&hlavicka1, soubor1) == K_CHYBNY_VSTUP || nacti_hlavicku(&hlavicka2, soubor2) == K_CHYBNY_VSTUP) { zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_CHYBNY_VSTUP); } // naalokujeme misto pro vektory if(alokuj_vektor(hlavicka1.pocet, vektor1) == K_NEDOSTATEK_PAMETI || alokuj_vektor(hlavicka2.pocet, vektor2) == K_NEDOSTATEK_PAMETI){ uvolni_vektor(*vektor1); uvolni_vektor(*vektor2); zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_NEDOSTATEK_PAMETI); } // nacte vektory ze souboru if(nacti_vektor(vektor1, soubor1) == K_CHYBNY_VSTUP || nacti_vektor(vektor2, soubor2) == K_CHYBNY_VSTUP) { uvolni_vektor(*vektor1); uvolni_vektor(*vektor2); zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_CHYBNY_VSTUP); } } void priprav_matice(Tmatice *matice1, Tmatice *matice2, Tmatice *matice3, FILE *soubor1, FILE *soubor2) { Thlavicka hlavicka1, hlavicka2; // nacte hlavicky souboru if(nacti_hlavicku(&hlavicka1, soubor1) == K_CHYBNY_VSTUP || nacti_hlavicku(&hlavicka2, soubor2) == K_CHYBNY_VSTUP) { zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_CHYBNY_VSTUP); } if(hlavicka1.sloupce != hlavicka2.radky) { // pokud nemuzeme s temito dvemi maticemi pocitat, vysledek je false printf("\nfalse\n"); } if(alokuj_matici(hlavicka1.radky, hlavicka1.sloupce, matice1) == K_NEDOSTATEK_PAMETI || alokuj_matici(hlavicka2.radky, hlavicka2.sloupce, matice2) == K_NEDOSTATEK_PAMETI || alokuj_matici(matice1->radky, matice2->sloupce, matice3) == K_NEDOSTATEK_PAMETI || hlavicka1.sloupce != hlavicka2.radky){ uvolni_matici(*matice1); uvolni_matici(*matice2); uvolni_matici(*matice3); zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_NEDOSTATEK_PAMETI); } // nacte vektory ze souboru if(nacti_matici(matice1, soubor1) == K_CHYBNY_VSTUP || nacti_matici(matice2, soubor2) == K_CHYBNY_VSTUP) { uvolni_matici(*matice1); uvolni_matici(*matice2); uvolni_matici(*matice3); zavri_soubor(soubor1); zavri_soubor(soubor2); exit(K_CHYBNY_VSTUP); } } void hledej_bubliny(int x, int y, Tmatice *matice) { matice->cisla[preved_index(x, y, *matice)] = 1; if(x - 1 >= 0) { if(matice->cisla[preved_index(x - 1, y, *matice)] == 0) { hledej_bubliny(x - 1, y, matice); // hledani nahoru } } if(y + 1 < matice->sloupce) { if(matice->cisla[preved_index(x, y + 1, *matice)] == 0) { hledej_bubliny(x, y + 1, matice); // doprava doprava } } if(x + 1 < matice->radky) { if(matice->cisla[preved_index(x + 1, y, *matice)] == 0) { hledej_bubliny(x + 1, y, matice); // hledani dolu } } if(y - 1 >= 0) { if(matice->cisla[preved_index(x, y - 1, *matice)] == 0) { hledej_bubliny(x, y - 1, matice); // hledani doleva } } } |
Projekt č. 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 | /* Projekt c.4 - Ceske razeni * Autor: Milan Seitler, xseitl01@fit.vutbr.cz * Skupina: 36 (1BIB) * Datum: 2010/12/17 * Nazev souboru: proj4.c * Popis programu: program zpracovava vstupni soubor a zpracovana data uklada do vystupniho souboru. Vstupni data lze filtrovat podle kriterii before/after a pred vstupem lze data jeste seradit vzestupne podle ceske abecedy. Program provadi zakladni kontrolu spravnosti vstupnich dat. Program lze spustit s temito parametry -h - napoveda --before / --after sloupec retezec - nepovinny parametr, lze pouzit jedno kriterium na jeden beh programu parametr sloupec urcuje pozici slova, se kterym bude porovnan parametr retezec. pokud slovo vyhovi (je abecedne pred nebo za), bude ulozeno do vystupniho souboru --print sloupec - povinny parametr, oznacuje nazev sloupce, ktery se ma tisknout --sort - nepovinny parametr, pokud je zadan, vystupni data se seradi vzestupne podle ceske abecedy */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> // kody chyb #define K_OK 0 //bez chyb #define K_CHYBNY_PARAMETR 1 // chybny parametr prikazove radky #define K_CHYBNY_VSTUP 2 // chybny vstup #define K_NEDOSTATEK_PAMETI 3 // nedostatek pameti #define K_SOUBOR_OTEVRIT 4 // chyba pri otevirani souboru #define K_SOUBOR_ZAVRIT 5 // chyba pri zavirani souboru // definice "typu" boolean #define FALSE 0 #define TRUE 1 // kody before a after #define NONE 0 #define BEFORE 1 #define AFTER 2 // kody pro sort #define SORT_NO 0 #define SORT_YES 1 // kody pro nacitani slov, urcuje specialni typ posledniho nacteneho znaku #define N_SPC 0 #define N_EOF 11 // zacina od 11 aby nekolidovalo s kody chyb, znamena EOF na konci slova #define N_PRAZDNY 12 // EOF pri preskakovani prazdnych znaku #define N_CRLF 13 // \n na konci slova #define N_CRLF_PRAZDNY 14 // \n // kody pro porovnani dvou retezcu, stejne jako strcmp #define P_STEJNE 0 #define P_PRED -1 #define P_ZA 1 // kod pro znak CH (vaha znaku) #define CH1 10 #define CH2 14 // kod pro maximalni vahu #define VAHA_MAX 256 typedef struct parametry { int filtr; // rozlisuje zda bylo pouzito before nebo after int sort; // rozlisuje zde se ma radit nebo ne char *f_retezec, *f_sloupec; // urcuje, ktery radek a sloupec se pouzije pri filtru before a after char *sloupec; // jmeno sloupce, ktery se bude tisknout char *vstup, *vystup; //nazvy vstupniho a vystupniho souboru } Tparam; typedef struct hlavicka { int pocet_sloupcu; // urcuje pocet sloupcu v tabulce int index_sloupce; // urcuje index sloupce, ktery budeme vypisovat int index_filtru; // urcuje index sloupce, podle ktereho se bude filtrovat (bude-li se filtrovat) } Thlav; typedef struct polozka Tpolozka; struct polozka { char *hodnota; // urcuje hodnotu (retezec) polozky Tpolozka *predchozi; // ukazatel na predchozi polozku v seznamu Tpolozka *dalsi; // ukazatel na nasledujici polozku v seznamu }; typedef struct seznam { Tpolozka *prvni_polozka; // ukazatel na prvni polozku seznamu Tpolozka *posledni_polozka; // ukazatel na posledni polozku seznamu int pocet_polozek; // pocet polozek seznamu } Tseznam; //----------------------------------------------------------------------------------------------- // prototypy funkci ----------------------------------------------------------------------------- int porovnej_slova(char *slovo1, char *slovo2); // porovna dve slova, funguje stejne jako strcmp, navic pracuje s ceskymi znaky void nacti_parametry(int argc, char *argv[], Tparam *x); //nacteni parametru z prikazove radky char *nacti_slovo(int *stav, FILE *soubor); // nacte slovo ze vstupniho souboru int nacti_hlavicku(Thlav *hlavicka, Tparam param, FILE *soubor); // nacita po slovech prvni radek souboru FILE *otevri_soubor(char *nazev, char *mod); // otevre soubor s nazvem *nazev int zavri_soubor(FILE *soubor); // zavru soubor, na ktery ukazuje ukazatel *soubor int vypis_chybu(int kod); // podle obdrzeneho chyboveho kodu vypiseme chybove hlaseni na stderr a ukoncime program void napoveda(); void vytvor_seznam(Tseznam *seznam); // inicializuje seznam void uvolni_seznam(Tseznam *seznam); // uvolni pamet alokovanou seznamem void pridej_polozku(Tseznam *seznam, Tpolozka *polozka); // prida polozku do seznamu Tpolozka *vytvor_polozku(char *data); // ze vstupni hodnoty (retezce) vytvori promennou typu Tpolozka int nacti_do_seznamu(Tparam parametry, Thlav hlavicka, Tseznam *seznam, FILE *soubor); // zpracuje souboru po slovech a ulozi // jednotlive polozky do seznamu void serad_seznam(Tseznam *seznam); // seradi polozky v seznamu podle jejich hodnot vzestupne dle ceske abecedy void zapis_seznam(Tseznam *seznam, FILE *soubor); // zapise hodnoty jednotlivych polozek do seznamu // prototypy funkci ----------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------- int main(int argc, char *argv[]) { Tparam param; // vytvorime instanci struktury Tparam pro zpracovani parametru Thlav hlavicka; // vytvorime instanci pro ulozeni udaju o hlavicce FILE *vstup = NULL, *vystup = NULL; Tseznam seznam; // vytvorime instanci struktury pro seznam nacti_parametry(argc, argv, ¶m); // nactene parametry ukladame do struktury // pokud nastane pri otevirani chyba, oznamime uzivateli a ukoncime program if((vstup = otevri_soubor(param.vstup, "r")) == NULL || (vystup = otevri_soubor(param.vystup, "w")) == NULL) { zavri_soubor(vstup); zavri_soubor(vystup); exit(vypis_chybu(K_SOUBOR_OTEVRIT)); } // po slovech nacte prvni radek (hlavicku) a ulozi udaje do struktury if(nacti_hlavicku(&hlavicka, param ,vstup) == K_CHYBNY_VSTUP) { zavri_soubor(vstup); zavri_soubor(vystup); exit(vypis_chybu(K_CHYBNY_VSTUP)); } // inicializujeme seznam vytvor_seznam(&seznam); // po slovech nacteme vstupni soubor, pokud nastane chyba, oznamime uzivateli a ukoncime program if(nacti_do_seznamu(param, hlavicka, &seznam, vstup) == K_CHYBNY_VSTUP) { zavri_soubor(vstup); zavri_soubor(vystup); exit(vypis_chybu(K_CHYBNY_VSTUP)); } // pokud byl zadan parametr before nebo after, seradime seznam if(param.sort == SORT_YES) { serad_seznam(&seznam); } // vysledny seznam zapiseme do souboru a uvolnime pamet zapis_seznam(&seznam, vystup); uvolni_seznam(&seznam); // pokud se soubor nepovede uzavrit, vypiseme chybove hlaseni a ukoncime program if(zavri_soubor(vstup) == K_SOUBOR_ZAVRIT || zavri_soubor(vystup) == K_SOUBOR_ZAVRIT) { exit(vypis_chybu(K_SOUBOR_ZAVRIT)); } return EXIT_SUCCESS; } // funkce porovna dva retezce, vraci hodnoty stejne jako strcmp, tedy < 0, 0 a > 0 (-1, 0, 1) int porovnej_slova(char *slovo1, char *slovo2) { // vytvorime dve tabulky s vahami znaku, jednu pro prvni pruchod a jednu pro druhy pruchod const unsigned char tabulka1[256] = { ['\0'] = 0, ['A'] = 1, ['a'] = 1, [(unsigned char) 'Á'] = 1, [(unsigned char) 'á'] = 1, ['B'] = 2, ['b'] = 2, ['C'] = 3, ['c'] = 3, [(unsigned char) 'Č'] = 4, [(unsigned char) 'č'] = 4, ['D'] = 5, ['d'] = 5, [(unsigned char) 'Ď'] = 5, [(unsigned char) 'ď'] = 5, ['E'] = 6, ['e'] = 6, [(unsigned char) 'É'] = 6, [(unsigned char) 'é'] = 6, [(unsigned char) 'Ě'] = 6, [(unsigned char) 'ě'] = 6, ['F'] = 7, ['f'] = 7, ['G'] = 8, ['g'] = 8, ['H'] = 9, ['h'] = 9, // kod 10 pro ch ['I'] = 11, ['i'] = 11, [(unsigned char) 'Í'] = 11, [(unsigned char) 'í'] = 11, ['J'] = 12, ['j'] = 12, ['K'] = 13, ['k'] = 13, ['L'] = 14, ['l'] = 14, ['M'] = 15, ['m'] = 15, ['N'] = 16, ['n'] = 16, [(unsigned char) 'Ň'] = 16, [(unsigned char) 'ň'] = 16, ['O'] = 17, ['o'] = 17, [(unsigned char) 'Ó'] = 17, [(unsigned char) 'ó'] = 17, ['P'] = 18, ['p'] = 18, ['Q'] = 19, ['q'] = 19, ['R'] = 20, ['r'] = 20, [(unsigned char) 'Ř'] = 21, [(unsigned char) 'ř'] = 21, ['S'] = 22, ['s'] = 22, [(unsigned char) '©'] = 23, [(unsigned char) 'ą'] = 23, ['T'] = 24, ['t'] = 24, [(unsigned char) '«'] = 24, [(unsigned char) '»'] = 24, ['U'] = 25, ['u'] = 25, [(unsigned char) 'Ú'] = 25, [(unsigned char) 'ú'] = 25, [(unsigned char) 'Ů'] = 25, [(unsigned char) 'ů'] = 25, ['V'] = 26, ['v'] = 26, ['W'] = 27, ['w'] = 27, ['X'] = 28, ['x'] = 28, ['Y'] = 29, ['y'] = 29, [(unsigned char) 'Ý'] = 29, [(unsigned char) 'ý'] = 29, ['Z'] = 30, ['z'] = 30, [(unsigned char) '®'] = 31, [(unsigned char) 'ľ'] = 31, ['0'] = 32, ['1'] = 33, ['2'] = 34, ['3'] = 35, ['4'] = 36, ['5'] = 37, ['6'] = 38, ['7'] = 39, ['8'] = 40, ['9'] = 41, ['-'] = 42 }; const unsigned char tabulka2[256] = { ['\0'] = 0, ['A'] = 1, ['a'] = 1, [(unsigned char) 'Á'] = 2, [(unsigned char) 'á'] = 2, ['B'] = 3, ['b'] = 3, ['C'] = 4, ['c'] = 4, [(unsigned char) 'Č'] = 5, [(unsigned char) 'č'] = 5, ['D'] = 6, ['d'] = 6, [(unsigned char) 'Ď'] = 7, [(unsigned char) 'ď'] = 7, ['E'] = 8, ['e'] = 8, [(unsigned char) 'É'] = 9, [(unsigned char) 'é'] = 9, [(unsigned char) 'Ě'] = 10, [(unsigned char) 'ě'] = 10, ['F'] = 11, ['f'] = 11, ['G'] = 12, ['g'] = 12, ['H'] = 13, ['h'] = 13, // kod 14 pro ch ['I'] = 15, ['i'] = 15, [(unsigned char) 'Í'] = 16, [(unsigned char) 'í'] = 16, ['J'] = 17, ['j'] = 17, ['K'] = 18, ['k'] = 18, ['L'] = 19, ['l'] = 19, ['M'] = 20, ['m'] = 20, ['N'] = 21, ['n'] = 21, [(unsigned char) 'Ň'] = 22, [(unsigned char) 'ň'] = 22, ['O'] = 23, ['o'] = 23, [(unsigned char) 'Ó'] = 24, [(unsigned char) 'ó'] = 24, ['P'] = 25, ['p'] = 25, ['Q'] = 26, ['q'] = 26, ['R'] = 27, ['r'] = 27, [(unsigned char) 'Ř'] = 28, [(unsigned char) 'ř'] = 28, ['S'] = 29, ['s'] = 29, [(unsigned char) '©'] = 30, [(unsigned char) 'ą'] = 30, ['T'] = 31, ['t'] = 31, [(unsigned char) '«'] = 32, [(unsigned char) '»'] = 32, ['U'] = 33, ['u'] = 33, [(unsigned char) 'Ú'] = 34, [(unsigned char) 'ú'] = 34, [(unsigned char) 'Ů'] = 35, [(unsigned char) 'ů'] = 35, ['V'] = 36, ['v'] = 36, ['W'] = 37, ['w'] = 37, ['X'] = 38, ['x'] = 38, ['Y'] = 39, ['y'] = 39, [(unsigned char) 'Ý'] = 40, [(unsigned char) 'ý'] = 40, ['Z'] = 41, ['z'] = 41, [(unsigned char) '®'] = 42, [(unsigned char) 'ľ'] = 42, ['0'] = 43, ['1'] = 44, ['2'] = 45, ['3'] = 46, ['4'] = 47, ['5'] = 48, ['6'] = 49, ['7'] = 50, ['8'] = 51, ['9'] = 52, ['-'] = 53 }; // inicializace promennych na vychozi hodnoty int vysledek = P_STEJNE; int delka = 0; int vaha1 = 0, vaha2 = 0; int i, j = 0, k = 0; int inc = 0; i = 0; // zjistime delku kratsiho ze dvou porovnavanych retezcu if(strlen(slovo1) < strlen(slovo2)) { delka = strlen(slovo1); } else { delka = strlen(slovo2); } // po znacich prochazime obe slova a porovnavame jejich vahy for(int i = j = k = 0; i <= delka; i++, j++, k++) { // musime osetrit, zda se ve slove nenachazi ch, pokud ano, nacteme dva znaky a posuneme se ve slove dal if((slovo1[j] == 'c' || slovo1[j] == 'C') && i < (delka - 1) && (slovo1[j + 1] == 'h' || slovo1[j + 1] == 'H')) { vaha1 = CH1; j++; inc = 1; // musime se posunout v cyklu kvuli ch } else { vaha1 = tabulka1[(unsigned char)slovo1[i]]; // nacteme vahu znaku if(vaha1 == 0 && slovo1[i] != '\0') { vaha1 = VAHA_MAX; } } if((slovo2[k] == 'c' || slovo2[k] == 'C') && i < (delka - 1) && (slovo2[k + 1] == 'h' || slovo2[k + 1] == 'H')) { vaha2 = CH1; k++; inc = 1; // musime se posunout v cyklu kvuli ch } else { vaha2 = tabulka1[(unsigned char)slovo2[i]]; // nacteme vahu znaku if(vaha2 == 0 && slovo2[i] != '\0') { vaha2 = VAHA_MAX; } } if(inc == 1) { // bylo nacteno ch - "posuneme se " v cyklu i++; } if(vaha1 > vaha2) { // porovname vahy vysledek = P_ZA; // pokud nejsou stejne, zmenime navratovou hodnotu funkce a ukoncime cyklus break; } else if(vaha1 < vaha2) { vysledek = P_PRED; break; } inc = 0; } if(vysledek == P_STEJNE) { // pokud jsou slova po prvnim pruchodu stejna, projdeme je jeste jednou s druhou tabulkou for(int i = j = k = 0; i <= delka; i++, j++, k++) { // osetreni ch, viz predchozi cyklus if((slovo1[j] == 'c' || slovo1[j] == 'C') && i < (delka - 1) && (slovo1[j + 1] == 'h' || slovo1[j + 1] == 'H')) { vaha1 = CH2; j++; inc = 1; } else { vaha1 = tabulka2[(unsigned char)slovo1[i]]; if(vaha1 == 0 && slovo1[i] != '\0') { vaha1 = VAHA_MAX; } } if((slovo2[k] == 'c' || slovo2[k] == 'C') && i < (delka - 1) && (slovo2[k + 1] == 'h' || slovo2[k + 1] == 'H')) { vaha2 = CH2; k++; inc = 1; } else { vaha2 = tabulka2[(unsigned char)slovo2[i]]; if(vaha2 == 0 && slovo2[i] != '\0') { vaha2 = VAHA_MAX; } } if(vaha1 > vaha2) { // porovname vahy znaku vysledek = P_ZA; break; } else if(vaha1 < vaha2) { vysledek = P_PRED; break; } inc = 0; } } return vysledek; } // funkce zpracuje parametry prikazove radky (parametry musi dodrzet stanovene poradi) // pokud jsou zadany neplatne parametry, vypiseme chybove hlaseni a ukoncime program void nacti_parametry(int argc, char *argv[], Tparam *x) { // inicializace promennych int chyba = K_OK; x->sort = SORT_NO; x->filtr = NONE; if(argc == 9 || argc == 8) { // pokud je zadano before / after if(strcmp("--after", argv[1]) == 0) { // ulozime do struktury udaje o filtrovani x->filtr = AFTER; } else if(strcmp("--before", argv[1]) == 0) { x->filtr = BEFORE; } else { chyba = K_CHYBNY_PARAMETR; } if(strcmp("--print", argv[4]) != 0) { chyba = K_CHYBNY_PARAMETR; } if(argc == 9) { // pokud je zadan parametr --sort if(strcmp("--sort", argv[6]) == 0) { x->sort = SORT_YES; } else { chyba = K_CHYBNY_PARAMETR; } } x->f_sloupec = argv[2]; // do struktury uklada udaje o sloupci a retezci pro filtrovani x->f_retezec = argv[3]; x->sloupec = argv[5]; } else if(argc == 6) { // pokud neni pouzito before nebo after if(strcmp("--print", argv[1]) != 0 || strcmp("--sort", argv[3]) != 0 ) { chyba = K_CHYBNY_PARAMETR; } x->sort = SORT_YES; x->sloupec = argv[2]; } else if(argc == 5) { if(strcmp("--print", argv[1]) != 0) { chyba = K_CHYBNY_PARAMETR; } x->sloupec = argv[2]; // napoveda -h } else if(argc == 2) { if(strcmp("-h", argv[1]) !=0) { chyba = K_CHYBNY_PARAMETR; } else { napoveda(); exit(EXIT_SUCCESS); } } else { chyba = K_CHYBNY_PARAMETR; } if(chyba == K_CHYBNY_PARAMETR) { exit(vypis_chybu(chyba)); } x->vstup = argv[argc - 2]; // nazev vstupniho souboru x->vystup = argv[argc - 1]; // nazev vystupniho souboru } // pokud jsou parametry neplatne, vypise se chybove hlaseni a program se ukonci // funkce nacita slova, na zacatku preskoci prazdne znaky, podle posledniho nacteneho znaku vraci ruzne hodnoty, // rozlisuje nacteni \n a EOF char *nacti_slovo(int *stav, FILE *soubor) { int i = 0; // index char znak; char *slovo = NULL, *slovo2 = NULL; // vytvorime dva retezce *stav = N_SPC; // nastavime defaultni stav na "dalsi znak za slovem je mezera" while(isspace((znak = getc(soubor))) && znak != EOF) { // preskocime prazdne znaky if(znak == '\n') { *stav = N_CRLF_PRAZDNY; // pokud nacteme \n, ukoncime cyklus a vratime jako stav "byl nacten konec radku" break; } } if(znak == EOF) { // pokud jsme pri preskakovani znaku nacetli EOF, jako stav vratime "byl nacten EOF pri preskakovani mezer" *stav = N_PRAZDNY; } ungetc(znak, soubor); // jeden nacteny znak vratime while(!isspace(znak = getc(soubor)) && znak != EOF) { // nacitame znaky dokud neni na vstupu EOF nebo prazdny znak if((slovo2 = realloc(slovo, (i + 2) * sizeof(char))) != NULL) { // realokace pameti pro retezec slovo = slovo2; slovo[i] = znak; // vzdy pridame 1 znak slovo[i + 1] = '\0'; // a na konec retezce ulozime \0 } else { free(slovo); // pokud se alokace nezdari, vypiseme chybove hlaseni a ukoncime program *stav = vypis_chybu(K_NEDOSTATEK_PAMETI); } i++; // zvetsime index } // menime navratove stavy podle posledniho nacteneho znaku // ------------------------------------------------------- if(znak == '\n' && *stav != N_CRLF_PRAZDNY) { *stav = N_CRLF; } if(znak == EOF && *stav != N_PRAZDNY) { *stav = N_EOF; } if((znak = getc(soubor)) == EOF) { *stav = N_EOF; } ungetc(znak, soubor); // ------------------------------------------------------- return slovo; } // po slovech nacita prvni radek souboru a udaje uklada do struktury int nacti_hlavicku(Thlav *hlavicka, Tparam param, FILE *soubor) { // inicializace promennych na vychozi hodnoty char *slovo = NULL; int nacti = N_SPC, i = 0; hlavicka->index_sloupce = -1; hlavicka->index_filtru = -1; do { // dokud nedojdeme na konec radku, nacitame jednotliva slova slovo = nacti_slovo(&nacti, soubor); if(nacti == N_CRLF_PRAZDNY) { // pokud nacteme neplatny znak, ukoncime cyklus free(slovo); break; } if(nacti == N_EOF || nacti == N_PRAZDNY) { // pokud nacteme neplatny znak, ukoncime cyklus nacti = K_CHYBNY_VSTUP; free(slovo); break; } if(porovnej_slova(slovo, param.sloupec) == 0) { // zjistime index sloupce, ktery se ma tisknout hlavicka->index_sloupce = i; } if(param.filtr != NONE) { if(porovnej_slova(slovo, param.f_sloupec) == 0) { // zjistime index sloupce, ve kterem se ma filtrovat hlavicka->index_filtru = i; } } i++; free(slovo); } while(nacti == N_SPC); hlavicka->pocet_sloupcu = i; // ulozime do struktury pocet sloupcu tabulky // pokud nebyl nalezen sloupec pro vypis nebo filtrovani, vypiseme chybove hlaseni a ukoncime program if(hlavicka->index_sloupce == -1 || (hlavicka->index_filtru == -1 && param.filtr != NONE)) { nacti = K_CHYBNY_VSTUP; } return nacti; } void napoveda() { printf("\n\n" "Ceske razeni\n" "Autor: Milan Seitler\n" "\n" "Spusteni programu: ./proj4 -h | --before / --after sloupec retezec --print sloupec --sort vstup.txt vystup.txt" "\n\n" "-h - napoveda\n" "--before / --after sloupec retezec - nepovinny parametr, lze pouzit jedno kriterium na jeden beh programu" " parametr sloupec urcuje pozici slova, se kterym bude porovnan parametr retezec. pokud slovo vyhovi" " (je abecedne pred nebo za), bude ulozeno do vystupniho souboru\n" "--print sloupec - povinny parametr, oznacuje nazev sloupce, ktery se ma tisknout\n" "--sort - nepovinny parametr, pokud je zadan, vystupni data se seradi vzestupne podle ceske abecedy\n" "\n\nProgram zpracovava data z tabulky ze vstupniho souboru, ktere filtruje a radi a vysledna data" " zapise do souboru.\n\n"); } FILE *otevri_soubor(char *nazev, char *mod) // otevre soubor s nazvem *nazev { FILE *soubor = NULL; // vytvorim si pomocny ukazatal na soubor soubor = fopen(nazev, mod); return soubor; // vratim ukazatel na soubor pripadne NULL } int zavri_soubor(FILE *soubor) // zavru soubor, na ktery ukazuje ukazatel *soubor { int chyba = K_OK; if(soubor != NULL) { // kdyz ukazatel na nic neukazuje, tak neni co zavrit if(fclose(soubor) == EOF) { chyba = K_SOUBOR_ZAVRIT; } // chyba pri zavirani -> chybove hlaseni a konec } return chyba; } int vypis_chybu(int kod) // podle obdrzeneho chyboveho kodu vypiseme chybove hlaseni na stderr a ukoncime program { switch(kod) { case K_CHYBNY_PARAMETR: fprintf(stderr, "\n\nChybny parametr prikazove radky! Program bude ukoncen. \n\n"); break; case K_CHYBNY_VSTUP: fprintf(stderr, "\n\nChybne slovo na vstupu! Zkontrolujte vstupni soubor a take zda se zadane parametry shoduji" " s hlavickou souboru. Program bude ukoncen. \n\n"); break; case K_NEDOSTATEK_PAMETI: fprintf(stderr, "\n\nNastala chyba pri rezervovani pameti! Program bude ukoncen. \n\n"); break; case K_SOUBOR_OTEVRIT: fprintf(stderr, "\n\nNastala chyba pri otevirani souboru! Pravdepodobne se pokousite otevrit neexistujici soubor. Program bude ukoncen. \n\n"); break; case K_SOUBOR_ZAVRIT: fprintf(stderr, "\n\nNastala chyba pri zavirani souboru! Program bude ukoncen. \n\n"); break; default: break; } return kod; } void vytvor_seznam(Tseznam *seznam) { // inicializace seznamu seznam->prvni_polozka = NULL; seznam->pocet_polozek = 0; } void uvolni_seznam(Tseznam *seznam) { // uvolneni alokovane pameti seznamu Tpolozka *pom_polozka; while(seznam->prvni_polozka != NULL) { // postupne uvolnujeme jednotlive polozky pom_polozka = seznam->prvni_polozka; seznam->prvni_polozka = pom_polozka->dalsi; free(pom_polozka->hodnota); free(pom_polozka); } } void pridej_polozku(Tseznam *seznam, Tpolozka *polozka) { // prida polozku na konec seznamu polozka->dalsi = NULL; if(seznam->prvni_polozka == NULL) { // pokud pridavame prvni polozku seznam->prvni_polozka = polozka; seznam->posledni_polozka = polozka; seznam->posledni_polozka->dalsi = NULL; // nastavime aby posledni polozka ukazovala na NULL } else { // pokud uz byla prvni polozka pridana polozka->predchozi = seznam->posledni_polozka; seznam->posledni_polozka->dalsi = polozka; seznam->posledni_polozka = polozka; seznam->posledni_polozka->dalsi = NULL; // nastavime aby posledni polozka ukazovala na NULL } } Tpolozka *vytvor_polozku(char *data) { // ze zadaneho retezce vytvori polozku seznamu Tpolozka *polozka = malloc(sizeof(Tpolozka)); // rezervujeme pamet pro polozku if(polozka != NULL) { polozka->hodnota = malloc((strlen(data) + 1) * sizeof(char));// rezervujeme pamet pro retezec polozka->hodnota[strlen(data)] = '\0'; // na konec pridame \0 for(unsigned int i = 0; i < strlen(data); i++) { polozka->hodnota[i] = data[i]; // zkopirujeme do hodnoty polozky retezec *data } } return polozka; } // po slovech nacita vstupni soubor a uklada hodnoty ze sloupce print do seznamu // pokud byl zadan parametr pro filtrovani, tak do seznamu ulozi pouze vyhovujici retezce int nacti_do_seznamu(Tparam parametry, Thlav hlavicka, Tseznam *seznam, FILE *soubor) { // inicializace promennych na vychozi hodnoty Tpolozka *polozka; int i = 0, nacti = N_SPC; char *slovo = NULL, *print = NULL; int filtruj = NONE; int uvolni = FALSE; do { // v cyklu nacitame slova dokud nedojdeme na konec souboru slovo = nacti_slovo(&nacti, soubor); // pokud nacteme EOF drive nez bylo "ocekavano", funkce vrati "chybovou hodnotu" if((nacti == N_PRAZDNY && i != hlavicka.pocet_sloupcu - 1) || (nacti == N_EOF && i != hlavicka.pocet_sloupcu - 1)) { nacti = K_CHYBNY_VSTUP; free(slovo); break; } if(nacti != N_CRLF_PRAZDNY) { // pokud se nachazime ve sloupci, podle ktereho se ma filtrovat, porovname slova a zjistime zda vyhovuji filtru if(parametry.filtr != NONE && i == hlavicka.index_filtru) { if(parametry.filtr == BEFORE) { if(porovnej_slova(slovo, parametry.f_retezec) < 0) { filtruj = BEFORE; } else { filtruj = NONE; } } else if(parametry.filtr == AFTER) { if(porovnej_slova(slovo, parametry.f_retezec) > 0) { filtruj = AFTER; } else { filtruj = NONE; } } } // pokud se nachazime ve sloupci, ktery se ma tisknout a je nutno uvolnit predchozi slovo, tak jej uvolnime // slova pro tisknuti se ukladaji do samostatne promenne, abychom si mohli pamatovat slovo a ulozit jej az po filtrovani if(i == hlavicka.index_sloupce) { if(uvolni == TRUE) { free(print); } print = malloc((strlen(slovo) + 1) * sizeof(char)); // alokujeme pamet pro novou promennou strncpy(print, slovo, strlen(slovo)); // zkopirujeme obsah do nove promenne print[strlen(slovo)] = '\0'; // na konec pridame \0 uvolni = TRUE; // vytvorili jsme novou promennou, budeme ji muset uvolnit } i++; // zvetsime index sloupce // pokud jsme dosli na konec radku, vytvorime ze retezce print polozku a ulozime ji do seznamu if(i == hlavicka.pocet_sloupcu) { if((filtruj != NONE && parametry.filtr != NONE) || parametry.filtr == NONE) { polozka = vytvor_polozku(print); pridej_polozku(seznam, polozka); seznam->pocet_polozek++; free(print); // uvolnime pamet uvolni = FALSE; // neni jiz treba nic uvolnit } i = 0; } } else { i = 0; } free(slovo); // uvolnime pamet } while(nacti != N_EOF && nacti != N_PRAZDNY); if(uvolni == TRUE) { free(print); } return nacti; } // funkce seradi seznam metodou bubble sort void serad_seznam(Tseznam *seznam) { Tpolozka *pol4 = NULL, *pol1 = NULL, *pol2 = NULL, *pol3 = NULL; // pomocne promenne typu polozka slouzi k prohozeni ukazatelu // v kazdem pruchodu cyklem nacteme do pomocnych promennych prvni polozky seznamu for(int i = 0; i < seznam->pocet_polozek; i++) { // prochazime cely seznam pol1 = seznam->prvni_polozka; if(pol1->dalsi != NULL) { // musime osetrit spatne pristupy do pameti pol2 = pol1->dalsi; } else { pol2 = pol1; } if(pol2->dalsi != NULL) { // musime osetrit spatne pristupy do pameti pol3 = pol2->dalsi; } else { pol3 = pol2; } pol4 = NULL; for(int j = 0; j < seznam->pocet_polozek - i - 1; j++) { // prochazime retezce po znacich if(porovnej_slova(pol1->hodnota, pol2->hodnota) > 0) { // pokud jsou slova ve spatnem poradi, prohodime je //prohozeni ukazatelu pol1->dalsi = pol2->dalsi; if(pol1->dalsi == NULL) { seznam->posledni_polozka = pol1; } pol2->dalsi = pol1; if(pol4 != NULL) { pol4->dalsi = pol2; } if(pol1 == seznam->prvni_polozka) { seznam->prvni_polozka = pol2; } // posuneme se v seznamu dale pol4 = pol2; pol1 = pol2->dalsi; pol2 = pol1->dalsi; if(pol3->dalsi != NULL) { pol3 = pol3->dalsi; } } else { // pokud jsou slova ve spravnem poradi, pouze se posuneme v seznamu pol4 = pol1; pol1 = pol2; pol2 = pol3; if(pol3->dalsi != NULL) { pol3 = pol3->dalsi; } } } } } // do souboru zapiseme hodnoty (retezce) jednotlivych polozek seznamu void zapis_seznam(Tseznam *seznam, FILE *soubor) { for(Tpolozka *polozka = seznam->prvni_polozka; polozka != NULL; polozka = polozka->dalsi) { fprintf(soubor, "%s\n",polozka->hodnota); } } |
Čti dál:
1 komentář k “Základy programování (IZP) – Projekt č. 3 a 4”
Odpověď na potapec
O mně
kategorie
SSME FI MUNI
FIT VUT
Odkazy
Inzerujte zde!
Kupte si odkaz! PR 3, SR 2
Inzerujte zde!
Kupte si odkaz! PR 3, SR 2
Inzerujte zde!
Kupte si odkaz! PR 3, SR 2
TAGS
2012
acta
akce
api
barcamp
bash
Bergamo
blog
brno
byznys
C
chytni svojdu
css
cufon
e-shop
facebook
filmy
FIT VUT
hobit
hokejový souboj
html
internet explorer
Iseo
IT
Itálie
komunikace
low-cost trip
mozilla firefox
objektově orientované programování
osobní rozvoj
parser
php
programování
python
pán prstenů
přednáška
regex
reinto
skript
spartacus
testování
url
volby 2013
vut
wordpress
Nejčtenější články
- První semestr na FIT VUT - 188 014 views
- 7 tipů Jak spát méně a efektivněji - 168 300 views
- Třetí semestr na FIT VUT - 166 243 views
- Jak v PHP nahradit zastaralé funkce ereg a eregi - 83 653 views
- Pátý semestr na FIT VUT - 62 695 views
- 7 tipů jak si usnadnit a urychlit práci s HTML a CSS - 57 489 views
- TEST: Kolik spánku je denně potřeba? - 53 278 views
- 9 nečekaně jednoduchých technik, které z vás udělají mistra komunikace - 44 566 views
- Čtvrtý semestr na FIT VUT - 40 250 views
- Druhý semestr na FIT VUT - 37 922 views
Nejnovější komentáře
- 5 nových tipů pro lepší spánek « Milan Seitler u 7 tipů Jak spát méně a efektivněji
- 5 nových tipů pro lepší spánek « Milan Seitler u TEST: Je možné spát 6 hodin denně? Tak určitě!
- David u 9 nečekaně jednoduchých technik, které z vás udělají mistra komunikace
- Petr u Bakalářské studium na FIT VUT
- Martin u Jak v PHP nahradit zastaralé funkce ereg a eregi
archiv
- Prosinec 2018
- Listopad 2015
- Září 2015
- Březen 2015
- Květen 2014
- Duben 2014
- Prosinec 2013
- Listopad 2013
- Červenec 2013
- Červen 2013
- Duben 2013
- Březen 2013
- Únor 2013
- Leden 2013
- Prosinec 2012
- Listopad 2012
- Říjen 2012
- Září 2012
- Srpen 2012
- Červenec 2012
- Červen 2012
- Květen 2012
- Březen 2012
- Únor 2012
- Leden 2012
- Listopad 2011
- Říjen 2011
- Srpen 2011
- Červen 2011
- Duben 2011
- Únor 2011
- Leden 2011
diky za inspiraci ale radeji pouziji insert sort :) jinak mi to pomohlo aspon malinko