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:
def longest_line(fname, encoding="UTF-8"): with open(fname, encoding=encoding) as f: return max((line for line in f), key=len) def longest_silly(fname, encoding="UTF-8"): line = "" with open(fname, encoding=encoding) as f: txt = f.read() pos, length = 0, -1 ind = txt.find("\n") while ind > -1: if ind - pos > length: length, line = ind - pos, txt[pos:ind] pos = ind+1 ind = txt.find("\n", pos) return lineHere 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
my @L = (q()); while(<>) { next if length $L[0] > length $_; @L = () if length $L[0] < length $_; push @L, $_; } return @L; }or you can do it with bash
x='' z=0 while read l do if [ $z -lt ${#l} then x=$l;z=${#l}; fi done echo $x