C :: Aufgabe #51 :: Lösung #1
2 Lösungen

#51
Spaltenbreite und Blocksatz
Anfänger - C
von bibir
- 03.09.2014 um 08:33 Uhr
Ein vorgegebener Text soll eingelesen und in einer bestimmten Spaltenbreite wieder ausgegeben werden.
Die Spaltenbreite N wird als Eingabeparameter vorgegeben. Der Text besteht aus "Wörtern", die durch Leerzeichen (Blank) getrennt sind. Unter einem "Wort" wird hier eine beliebige zusammenhängende Zeichenkette verstanden, wobei jedes Zeichen eine Druckstelle einnimmt.
Der Text soll ausgerichtet werden an den beiden Spaltenrändern, und die zusätzlich einzuführenden Blanks sollen möglichst gleichmäßig auf die Zwischenräume zwischen den Wörtern verteilt werden.
Der Text beginnt in einer Spalte grundsätzlich linksbündig, Wörter, die länger sind als die Spaltenbreite, werden am rechten Rand ohne Trennzeichen zwangsweise getrennt. Silbentrennung darf nicht durchgeführt werden.
Die Spaltenbreite N wird als Eingabeparameter vorgegeben. Der Text besteht aus "Wörtern", die durch Leerzeichen (Blank) getrennt sind. Unter einem "Wort" wird hier eine beliebige zusammenhängende Zeichenkette verstanden, wobei jedes Zeichen eine Druckstelle einnimmt.
Der Text soll ausgerichtet werden an den beiden Spaltenrändern, und die zusätzlich einzuführenden Blanks sollen möglichst gleichmäßig auf die Zwischenräume zwischen den Wörtern verteilt werden.
Der Text beginnt in einer Spalte grundsätzlich linksbündig, Wörter, die länger sind als die Spaltenbreite, werden am rechten Rand ohne Trennzeichen zwangsweise getrennt. Silbentrennung darf nicht durchgeführt werden.
#1

von devnull (8870 Punkte)
- 15.10.2014 um 07:49 Uhr
Lösung 1 mit den traditionellen C-String- und Ausgabefunktionen. Hat Probleme bei der Darstellung von Texten mit Sonderzeichen (z.B. Umlaute).
Aufrufbeispiel: englischer Text, Spaltenbreite 72:
C-Code
Aufrufbeispiel: englischer Text, Spaltenbreite 72:
Konsolenausgabe:
$ ./blocksatz "$(cat en.txt)" 72
The goal of the Linux Documentation Project (LDP) is to create and
distribute a canonical set of high quality free GNU/Linux documentation.
An additional goal is to collaborate on all issues of GNU/Linux
documentation. We hope to establish a high quality system of
documentation that is easy to use and search. This includes integration
of a commented list of all the major documentation sites with similar
goals. The LDP is essentially a loose team of volunteers with minimal
central organization. Anyone who would like to help is welcome to join
...

/********************************************* * blocksatz.c Textformatierung im Blocksatz *********************************************/ #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <ctype.h> #include <string.h> #define LINE_BUFFER_SIZE 200 #define WORDS_PER_LINE 50 // Spaltenbreite global int gcolumn_width; // Textparser (Wortsuche) char* parse_text(char *start, int maxlen, int backstep) { static char *w; // begin of word static char *p; // pointer to next char static char csav=0; // char replaced by '\0' if (csav) { *p = csav; csav = 0; } if (backstep) return (w)?p=w:NULL; if (start) p = start; while (*p && isspace(*p)) p++; w = p; while (*p && !isspace(*p) && p - w < maxlen) p++; if (*p) { csav = *p; *p = '\0'; } return (p - w)?w:NULL; } // Hole naechstes Wort mit Maximallaenge char *getword(char *word, int maxlen) { return parse_text(word, maxlen, 0); } // Letztes Wort wieder einstellen char *ungetword(void) { return parse_text(NULL, 0, 1); } // Ausgabe einer Textzeile im Blocksatz // nwrd : Anzahl Worte // nspc : Anzahl Blanks zur Verteilung // words : Zeiger auf Wortliste void print_line(int nwrd, int nspc, char **words) { int min_spc, res_spc; int gap, ng, nw; --nwrd; min_spc = (nwrd && nspc) ? (nspc/nwrd) : 1; res_spc = nspc - min_spc*nwrd; for (nw=0; nw<=nwrd; nw++) { printf("%s", words[nw]); if (nw < nwrd) { gap = min_spc + ((nwrd-nw<=res_spc)?1:0); for (ng=0; ng<gap; ng++) putchar(' '); } } putchar('\n'); } // Hauptfunktion: Textformatierung im Blocksatz void format_text(char *text) { char line_buffer[LINE_BUFFER_SIZE]; char *words_list[WORDS_PER_LINE]; char *word, *lbpos; int cwords = 0; int clines = 0; int cleft, wlen; lbpos = line_buffer; cleft = gcolumn_width; if ((word = getword(text, gcolumn_width)) != NULL) { do { wlen = strlen(word); memcpy(lbpos, word, wlen+1); words_list[cwords++] = lbpos; lbpos += wlen + 1; cleft -= wlen; if (cleft < cwords) { if (cleft < cwords-1) { ungetword(); cleft += wlen; cwords--; } print_line(cwords, cleft, words_list); clines++; cwords = 0; cleft = gcolumn_width; lbpos = line_buffer; } } while ((word = getword(NULL, gcolumn_width)) != NULL); } if (cwords > 0) { print_line(cwords, 0, words_list); clines++; } printf("column width %d, total %d lines\n", gcolumn_width, clines); } // main int main(int argc, char **argv) { char *ptext; int iopt; if (argc > 1) { iopt = (argc==2)?0:2; gcolumn_width = (iopt)?atoi(argv[iopt]):60; if ((ptext = strdup(argv[1])) != NULL) { format_text(ptext); free(ptext); } } return 0; }
Kommentare:
Für diese Lösung gibt es noch keinen Kommentar
Seite 1 von 0
1