Longest Line
April 18, 2017
We begin with a Scheme solution, since that is the primary language of this blog:
(define (longest-line file-name) (with-input-from-file file-name (lambda () (let loop ((line (read-line)) (max-len 0) (max-line "")) (cond ((eof-object? line) max-line) ((< max-len (string-length line)) (loop (read-line) (string-length line) line)) (else (loop (read-line) max-len max-line)))))))
I’ve spent a lot of time programming in Awk, so this solution popped quickly into my mind:
awk ' length > max_length { max_length = length longest_line = $0 } END { print longest_line } ' < filename
That’s written for clarity; in real life, at an interactive command prompt, I would probably write it like this:
awk 'length>m{m=length;l=$0} END{print l}' <filename
My third solution combines standard unix tools:
cat filename | awk '{print length, $0}' | sort -n | tail -1 | sed 's/[0-9]* //'
Here’s my fourth solution; I’ll leave it to you figure out how it works:
sed -rn "/.{$(expand -t1 filename | wc -L)}/p" filename
You can run the Scheme version of the program at http://ideone.com/8jNtqJ.
Option 1:
wc -L filename
Option 2:
Here are two solutions: Perl 5 and C11. They both expect filenames to be passed as command line arguments (- for stdin).
The Perl solution:
#!/usr/bin/env perl
my $longest = "\n";
while (<>) {
$longest = $_ if (length($longest) < length);
}
print "length: " . length($longest) . "\n";
print "longest: " . $longest;
The C11 solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
const size_t max_line_length = 1024;
char *filename;
FILE *fp;
char line[max_line_length];
char longest[max_line_length];
int err;
longest[0] = '\0';
for (int i = 1; i < argc; ++i) {
filename = argv[i];
if (strcmp(filename, "-") == 0) {
fp = stdin;
} else {
fp = fopen(filename, "r");
if (fp == NULL) {
perror(filename);
continue; // ignore bad files
}
}
while (fgets(line, max_line_length, fp) != NULL) {
if (strlen(line) > strlen(longest)) {
(void)memcpy(longest, line, max_line_length);
}
}
if (!feof(fp)) {
err = fprintf(stderr, "There was an error while reading %s.\n", filename);
if (err < 0) {
exit(1);
}
}
}
printf("length: %zd\n", strlen(longest));
printf("longest: %s", longest);
exit(0);
}
Returning all the longest lines in perl
or you can do it with bash