aboutsummaryrefslogtreecommitdiff
path: root/ch1/1-16_longest-line.c
diff options
context:
space:
mode:
authorIsa Hassen <hassen.isa@gmail.com>2015-12-18 19:40:12 -0500
committerzlg <zlg@zlg.space>2015-12-19 17:43:20 -0800
commit032b64e37a23541e136dcf082a4564023579ed39 (patch)
tree25d4aa1bab0316ed9fc28f353bb1b38d5e02cc87 /ch1/1-16_longest-line.c
parentSolve Exercise 7-1: `upper` and `lower` (diff)
downloadknr-032b64e37a23541e136dcf082a4564023579ed39.tar.gz
knr-032b64e37a23541e136dcf082a4564023579ed39.tar.bz2
knr-032b64e37a23541e136dcf082a4564023579ed39.tar.xz
knr-032b64e37a23541e136dcf082a4564023579ed39.zip
Re-solve Exercise 1-16: arbitrarily long maxline
A completely rewritten solution which follows the spec given in the book exactly; make the program work for arbitrarily long input lines while modifying `main()` only. I've only changed the name of the macro MAXLINE to BUFFSIZE for clarity - otherwise the code is typed up exactly as found in the book. It demonstrates the use of a buffer without modifying any of the helper functions.
Diffstat (limited to '')
-rw-r--r--ch1/1-16_longest-line.c104
1 files changed, 60 insertions, 44 deletions
diff --git a/ch1/1-16_longest-line.c b/ch1/1-16_longest-line.c
index 137bb11..450d990 100644
--- a/ch1/1-16_longest-line.c
+++ b/ch1/1-16_longest-line.c
@@ -9,55 +9,71 @@
* Answer: The key to arbitrary limits is buffering. Using a buffer allows you
* to tackle a problem in chunks of memory instead of all at once. It's
* slightly more complicated, but adds usefulness to a program.
+ *
+ * This solution, which was contributed by Isa (ibnIrshad), follows the spec
+ * exactly, by only modifying main(), unlike many other solutions on the
+ * internet.
+ *
+ * Assumptions:
+ * 1. "arbitrarily long" is interpreted to mean upto the maximum size of an
+ * integer on the given architechture, e.g. 2^32 unsigned on a 32-bit machine.
+ * Indeed a string of that size would be larger than 4 gigabytes.
+ * It is possible to deal with numbers larger than that, but it involves a great
+ * deal of work abstracting away the concept of an integer, similar to
+ * dynamically sized arrays.
+ *
+ * 2. EOF signal (Ctrl-D) must be given on an empty line
*/
+#define BUFFSIZE 5 /* renamed MAXLINE and reduced it to 5 to demonstrate
+we can handle lines much greater than this number*/
+
+int getlinelen(char line[], int maxline);
+void copy(char to[], char from[]);
+
+/* print longest input line */
+main()
+{
+ /* len of current line, max len seen so far, templen of buffer */
+ int len, max, templen;
+ char buffer[BUFFSIZE];
-#define MAXLENGTH 100
-
-int get_line(char s[], int lim) {
- /* Put as much as possible into a temp string, and count its length */
- int c, i;
-
- for (i = 0; i < lim && (c = getchar()) != EOF && c != '\n'; ++i) {
- s[i] = c;
- }
- if (c == '\n') {
- s[i] = c;
- ++i;
- }
- s[i] = '\0';
- return i;
+ max = len = 0;
+
+ while ((templen = getlinelen(buffer, BUFFSIZE)) > 0) {
+ len += templen;
+
+ if (buffer[templen-1] == '\n'){
+ if (len > max)
+ max = len;
+ len = 0;
+ }
+ }
+ printf("\nLen of longest line: %d\n", max);
+ return 0;
}
-void copy(char from[], char to[]) {
- int i = 0;
+/* getlinelen: read a line into s, return length */
+int getlinelen(char s[], int lim)
+{
+ int c, i;
- while ((to[i] = from[i]) != '\0') {
- ++i;
- }
+ for (i=0; i<lim-1 && (c=getchar()) != EOF && c!='\n'; ++i)
+ s[i] = c;
+ if (c == '\n') {
+ s[i] = c;
+ ++i;
+ }
+ s[i] = '\0';
+ return i;
}
-int main() {
- int len, max;
-
- char line[MAXLENGTH];
- char longest[MAXLENGTH];
-
- max = 0;
- while ((len = get_line(line, MAXLENGTH)) > 0) {
- if (len > max) {
- max = len;
- copy(line, longest);
- }
- }
-
- printf("\nThe longest line is %3d characters long.\n", max);
- printf("----------------------------------------\n");
- if (max > 0) {
- printf("%-s", longest);
- if (max == MAXLENGTH && longest[max - 1] != '\n') {
- printf("\n");
- }
- }
-
- return 0;
+
+/* copy: copy 'from into 'to'; assume to is big enough */
+void copy(char to[], char from[])
+{
+ int i;
+
+ i = 0;
+ while ((to[i] = from[i]) != '\0')
+ ++i;
}