/* * tulosta.c C-ohjelmoinnin harjoitustyö, Launo Tuuri (c) 1997 * --------- * * Tarkoitus: Tulosta riveittäin saadut sanat stdout:iin muotoillen ne * globaalin muuttujan int tasaa ja parametrinä välitetyn * int rivpit arvojen mukaan. Tarvittaessa yritä tavuttaa rivin * viimeinen sana. * * Käytetyt globaalit muuttujat: int tasaa * char tul_pusk[] * * Funktiot: static int ei_tekstia(char *sana) * static int voiko_jakaa(char *sana) * static void tarkasta(char *sana, int rivpit) * static void venyta(char *rivi, int rivpit) * static void pois_eka_valil(char* rivi) * static int ota(char *sana) * void tulosta(char *rivi) */ #include #include #include #include "ht.h" /* Tästä tiedostosta käsin käytetyt muitten tiedostojen funktiot: */ /* jaa.c: */ void jaa(char *sana, int tilaa); extern int tasaa; extern char tul_pusk[]; /* * Funktion tarkoitus: Tarkasta, onko sanassa vain yhtä merkkiä mahdollisten * välilyönti- yms. merkkien lisäksi * Parametrit: sana merkkijonona * Palautus: 1, jos annettu merkkijono ei merkkiensä puolesta * vaikuta sanalta, muuten 0 */ static int ei_tekstia(char *sana) { int a, i = 0, j; while (isspace(sana[i]) && i < strlen(sana)) ++i; a = sana[i++]; for (j=i; j rivpit) { fprintf(stderr, "Huom: sana \"%s\"\n katkaistiin, " "että se mahtuisi riville\n\a", sana); sana[rivpit-1] = '\0'; } strcat(sana, tul_pusk); strcpy(tul_pusk, sana); sana[0] = '\0'; } } /* * Funktion tarkoitus: Venytä riviä lisäämällä sanojen väliin tyhjiä * välilyöntyejä, kunnes rivi on halutun pituinen * Parametrit: rivi merkkitaulukkona, haluttu rivinpituus */ static void venyta(char *rivi, int rivpit) { int i = 0, n = 1, apu1, apu2, krt = 0; register int j; while (strlen(rivi) < rivpit) { if (i >= strlen(rivi) - 2) { i = 0; ++n; } if (isspace(rivi[i])) { i += n; j = i; if (!isspace(rivi[j])) { apu2 = rivi[j]; rivi[j] = ' '; while (rivi[j]) { apu1 = rivi[++j]; rivi[j] = apu2; apu2 = apu1; } } } ++i; ++krt; if (krt > MAX_RP) break; } } /* * Funktion tarkoitus: Poista rivin alusta ensimmäinen merkki kunnes * ensimmäinen merkki on jokin muu kuin välilyönti- tms. merkki * Parametrit: osoite riviin */ static void pois_eka_valil(char* rivi) { int i; while (isspace(rivi[0])) { for (i=1; rivi[i]; ++i) rivi[i-1] = rivi[i]; rivi[i-1] = '\0'; } } /* * Funktion tarkoitus: Ota tulostuspuskurista yksi sana. Siirrä sana * parametrina saatuun merkkitaulukkoon ja poista sana * tulostuspuskurista. * Parametrit: osoite merkkijonotaulukkoon * Palautus: 1 jos onnistui, muuten 0 */ int ota(char *sana) { int i = 1, j = 0; char apu[MAXSRP+MAX_RP]; if (tul_pusk[0] == '\0') { sana[0] = '\0'; return 0; } sana[0] = tul_pusk[0]; for (; tul_pusk[i] != ' ' && tul_pusk[i]; ++i) sana[i] = tul_pusk[i]; sana[i] = '\0'; while (tul_pusk[i]) apu[j++] = tul_pusk[i++]; apu[j] = '\0'; strcpy(tul_pusk, apu); return 1; } /* * Funktion tarkoitus: Siirrä saatu rivi tulostuspuskuriin (globaaliin * merkkitaulukkoon) ja tulosta sanoittain valmiita, muotoiltuja * rivejä. Jos saatu rivi on pelkkä "\n" tulosta tulostuspuskuriin * jääneet sanat ja aloita uusi kappale. * Parametrit: osoite merkkijonotaulukkoon, jossa tulostettavia sanoja ja * haluttu rivin pituus * Palautus: - */ void tulosta(char *rivi, int rivpit) { char apu[MAXSRP+MAX_RP]; char sana[MAXSRP]; if (!strcmp(rivi, "\n")) { pois_eka_valil(tul_pusk); printf(tul_pusk[0] ? "%s\n\n" : "%s\n", tul_pusk); tul_pusk[0] = '\0'; } else { strcat(tul_pusk, rivi); while (strlen(tul_pusk) >= rivpit) { apu[0] = sana[0] = '\0'; while(ota(sana)) { if ((strlen(apu) + strlen(sana)) <= rivpit) strcat(apu,sana); else { tarkasta(sana, rivpit); if (sana[0]) { jaa(sana, rivpit-strlen(apu)); strcat(apu, sana); } pois_eka_valil(apu); if (tasaa) venyta(apu, rivpit); printf("%s\n", apu); break; } } } } }