views:

3373

answers:

56

I got inspired to try out Haskell again based on a recent answer. My big block is that reading a file line by line (a task made simple in languages such as Perl) seems complicated in a functional language. How do you read a file line by line in your favorite language?


So that we are comparing apples to other types of apples, please write a program that numbers the lines of the input file. So if your input is:

Line the first.
Next line.
End of communication.

The output would look like:

1       Line the first.
2       Next line.
3       End of communication.

I will post my Haskell program as an example.


Ken commented that this question does not specify how errors should be handled. I'm not overly concerned about it because:

  1. Most answers did the obvious thing and read from stdin and wrote to stdout. The nice thing is that it puts the onus on the user to redirect those streams the way they want. So if stdin is redirected from a non-existent file, the shell will take care of reporting the error, for instance.

  2. The question is more aimed at how a language does IO than how it handles exceptions.

But if necessary error handling is missing in an answer, feel free to either edit the code to fix it or make a note in the comments.

+8  A: 

Haskell

The output of my version applied to its own source:

1       main =  interact numberLines
2
3       numberLines :: String -> String
4       numberLines s = 
5           unlines $ zipWith (\a b -> show a ++ "\t" ++ b) [1..] (lines s)

Notes:

  1. I'm still learning Haskell and I found the problem far more challenging than the size of my source code indicates. And it had nothing to do with monads. The best explanation of IO in Haskell I found was Learn You a Haskell for Great Good!. It's a much better tutorial than the title suggests.

  2. The hard part was actually creating the numberLines function and getting all the types worked out. The lambda expression was originally a named function so that the error messages were more meaningful as I worked. Putting the type declaration at the top of a function was more helpful than I initially anticipated since it documents how you can chain functions together. It took a lot of reading to discover that show converted the line numbers into a form I could concatenate to the line.

  3. ephemient has posted another Haskell example and confirmed that it will work incrementally. All of the functions are lazy, so it meets the requirement of reading line by line. To verify, I used the following test from the command line:

    $ strings /dev/random | runhaskell line_count.hs
    
Jon Ericson
+8  A: 

C++

/* plain copy */
copy(istream_iterator<char>(cin), istream_iterator<char>(),
     ostream_iterator<char>(cout));

/* with line numbers */
string line;
size_t n = 0;
while (getline(cin, line)) {
  ++n;
  cout << n << line << endl;      
}

C

const int MAX_LINE = 255;
/* ... */
char buf[ MAX_LINE ];
size_t n = 0;
while(fgets(buf, sizeof buf, stdin) != NULL) {
   ++n;
   printf("%u %s\n", n, buf);
}

C(With dynamic memory)

FILE *fptr;
char *buf;
int flen;
/*open the file*/
fptr = fopen("foo", "r+");

/*get the length of the file and allocate the memory for it*/
fseek(fptr, 0, SEEK_END);
flen = ftell(fptr);
rewind(fptr);

buf = (char*)malloc(flen);

/*and now we break into the routine from above, suitably modified*/
while(fgets(buf, flen, fptr) != NULL) {
   ++n;
   printf("%u %s\n", n, buf);
}
dirkgently
MAX_LINE makes me sad. Poor C.
Jon Ericson
MAX_LINE whispers "put on your black hat."
Thomas L Holaday
Does fgets strip the EOL? I think the \n is redundant in the printf. However, you need test that there is an EOL in the while loop to make sure you need to print a new line number.
jmucchiello
No, it doesn't until and unless you explicitly remove it from the buffer.
dirkgently
+21  A: 

Python

Python is my language of choice. Here is how such an operation would go:

myfile = open('foo.txt')

for index, line in enumerate(myfile):
    print '%i  %s' % (index, line)

done!


A more general version:

#!/usr/bin/env python
import fileinput, sys

for n, line in enumerate(fileinput.input()):
    sys.stdout.write("%d\t%s" % (n+1, line))
vezult
I don't think this appends a line number to the line. Does it?
Jon Ericson
You should change the for line in myfile to for index,line in enumerate(myfile) to show an index number as well.
Geo
ok, I added the line numbers. Good catch!
vezult
Numbering from 0 is a bold choice. ;-)
Jon Ericson
It's not quite in line with the question's instructions, but it bolsters my comp-sci cred. ;o)
vezult
I've added version with fileinput. It works similar to the perl's code.
J.F. Sebastian
btw, @vezult's version prints empty lines between each line in the input (one newline from `line` plus one from `print`)
J.F. Sebastian
+5  A: 

VB.Net

1       Dim fileStream As New FileStream(filePath, Open)
2       Dim fileReader As New StreamReader(fileStream)
3       Dim lineNumber As Integer = 0
4       While Not fileReader.EoF
5           Dim line As String = fileReader.ReadLine()
6           Debug.WriteLine(String.Format("{0}: {1}",lineNumber, line)
7           lineNumber += 1
8       End While
9       fileReader.Dispose
10      fileStream.Dispose
Stephen Wrighton
+13  A: 

C#

using (var reader = File.OpenText(path))
{
    int lineNumber = 1;
    while (!reader.EndOfStream)
        Console.WriteLine("{0} {1}", lineNumber++, reader.ReadLine());
}

And with the addition of LINQ C# has functional monads.

Kris
Could you add the line number?
Jon Ericson
Thanks. C# looks slightly alien to this C/Perl programmer.
Jon Ericson
using: auto disposes the io stream; var: shorthand (not variant) still strongly typed in the compiler.
Kris
You can simplify this somewhat by using !reader.EndOfStream, dropping the line variable, and moving the ReadLine() inside the call to WriteLine. (If you move the declaration of lineNumber outside the using, you can also get rid of the brackets)
Daniel LeCheminant
Thanks Daniel! I made the adjustments you recommended.
Kris
If you move lineNumber outside of the using, you can drop the brackets too (That makes it "look" somewhat simpler...)
Daniel LeCheminant
That's true. However I wanted to emphasize the "using" at the beginning of the code snippet; mostly to promote curiosity about IDisposable in the readership.
Kris
+19  A: 

Perl 5

#!/usr/bin/env perl
while (<>) { print "$.\t$_" }
toolkit
Yep. Nice and easy. ;-)
Jon Ericson
not to start a golf war, but I think this will work too:#!/usr/bin/perl -n -e print "$.\t$_"
chris
Shorter: perl -pe 's/^/$.\t/'
Jon Ericson
(But this is how Perl gets a bad name. Stick with toolkit's answer. ;-)
Jon Ericson
or print "$.\t$_" while (<>);
Alnitak
I like Toolkit's answer. Short and sweet enough to get the job done concisely, but long enough that you don't have to know obscureta of Perl.
Paul Nathan
+9  A: 

Java

This is the simple version, not worrying about try/catch blocks:

BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;
int i = 1;
while ((line = reader.readLine()) != null) {
    System.out.println(i + "\t" + line);
    i++;
}
reader.close();

The way I would handle exceptions is to wrap this in a method:

private void printLinesWithNumbers()
    throws FileNotFoundException, IOException {
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader(fileName));
        String line;
        int i = 1;
        while ((line = reader.readLine()) != null) {
            System.out.println(i + "\t" + line);
            i++;
        }
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException ex) {
                //FileReaders never throw exceptions on close()
                //and we're in a catch block, so we're not supposed to
                //throw anything anyway
            }
        }
    }
}

Now isn't that pretty? Take that, Java-haters!

Alternatively

BufferedReader reader = new BufferedReader(new FileReader(fileName));
String line;

for (int i = 1; (line = reader.readLine()) != null; i++)
    System.out.println(i + "\t" + line);

reader.close();
Michael Myers
Joke... it's a joke...
Michael Myers
You forgot to print the tabs! Also, shouldn't you use some LinePrinterVisitor design pattern? :-)
benzado
Tabs I'll do, but I don't have time to write the AbstractLinePrinterVisitorFactory that this really deserves. ;)
Michael Myers
Ignore StreamTokenizer, nothing to see here, move along.
Tim Williscroft
System.out? Think that should probably be SLF4J so that you aren't bound to one particular means of outputting to the console.
MandyK
+10  A: 

MATLAB

fid = fopen(fileName);
i=0;
while ~feof(fid)
   i=i+1;
   tline = fgetl(fid);
   disp([num2str(i), '000%d'), '  ', tline]);
end
fclose(fid)
Azim
didn't expect to see this here. +1
Geo
+2  A: 

VB6 / VBA

Private Sub ReadFile(ByVal pFilePath As String)

  Dim iFileNum As Integer
  Dim iCtr As Integer
  Dim sLine As String

  iCtr = 0
  iFileNum = FreeFile

  Open pFilePath For Input As #iFileNum

  Do While Not EOF(iFileNum)
    iCtr = iCtr + 1
    Input #iFileNum, sLine
    Debug.Print iCtr; sLine
  Loop

  Close #iFileNum

End Sub
DJ
+5  A: 
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.PrintWriter;

public class LineReaderWriter {
    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
        LineNumberReader in = new LineNumberReader(new FileReader(args[0]));
        in.setLineNumber(1);
        while (in.ready()) {
            out.printf("%d\t%s%n", in.getLineNumber(), in.readLine());
        }
        out.close();
    }
}
toolkit
Is %n a Java thing?
Daniel LeCheminant
%n is a platform-independent newline character in Java's formatting syntax.
Michael Myers
@mmeyers: Neat :-]
Daniel LeCheminant
+14  A: 

Bash

#!/bin/bash
cat -n $1

:)

Edit: Don't like using "cat"? Try nl instead.

#!/bin/bash
nl $1

And to make it compliant with the assignment:

#!/bin/bash
nl -n ln $1
Marty Lamb
Too easy! But that's exactly what the Bourne shell is designed for.
Jon Ericson
Who the heck decided to give `cat` options?? Oh well.
ephemient
Added "nl" solution.
Barry Brown
+4  A: 

Groovy

One line version.

new File(filename).readLines().eachWithIndex() { line, index -> println " ${index + 1} ${line}" };

Multiline version, more readable.

file = new File(filename);
lines = file.readLines();
lines.eachWithIndex() { line, index -> println " ${index + 1} ${line}" };
Steve K
+11  A: 

PHP

<?php
foreach ( file($inputFile) as $line ) {
    echo (++$rowNumber)."\t".$line.PHP_EOL;
}

For STDIN:

<?php
$i=0;
while ($line = fgets(STDIN)) echo ++$i."\t".$line;
Henrik Paul
Will file() satisfy the line-by-line requirement?
Ben Dunlap
file() is a poorly named function that reads a file into an array so that each element is a line of text. So, although PHP internally reads the file entirely and only then chunks it, I think it should satisfy it. There's no true file streams available, afaik.
Henrik Paul
That will throw a NOTICE-level error for $rowNumber uninitialized. Would be simpler just to do: foreach ( file($inputFile) as $rowNumber => $line ) echo $rowNumber."\t".$line.PHP_EOL;
Zarel
While Zarel is actually right, I'd like to point out that the NOTICE will not appear until you raise the default warning level.
Henrik Paul
+8  A: 

It's pretty simple in bash as well:

#! /bin/bash

count=0
while read line; do
  echo "$count $line"
  count=$((count + 1))
done < $0
vezult
it's not quite as practical as using cat -n, but it uses shell builtins this way.
vezult
+7  A: 

Bash

nl testfile

the output is nice:

$ nl testfile
     1  line one
     2  line two 
     3  line three
Rick Bunker
+9  A: 

Python

with open("me.txt") as f:
    for number, line in enumerate(f):
        print('%d\t%s' % (number + 1, line.strip()))

This version has the advantage over the one above that it closes the file descriptor even if an exception occurs. This runs in Python 2.6 and 3.0 with no modifications, and will run in Python 2.5 if you do from __future__ import with_statement first

Armin Ronacher
any particular reason to use sys.stdout over print?
SilentGhost
Same syntax across python2.x and 3 ?
Martin Beckett
with become a keyword in 2.6, so it's kind of pointless to try to preserve syntax
SilentGhost
print adds a newline to the end which is already in "line". Now either I could line.rstrip() whitespace or I just call sys.stdout.write :)
Armin Ronacher
print x, ?
SilentGhost
So no linenumbers then, as per the question?
Phil H
Added line number s:) @SilentGhost: print x, adds a soft space after the line.
Armin Ronacher
my point was that you might as well py3k syntax ;)
SilentGhost
I've simplified the code a bit, you can do print("blah %s" % (a)) in any version of python (from v1.0.1 onwards..)
dbr
+5  A: 

Clojure

(use '(clojure.contrib duck-streams seq-utils))
(dorun 
 (for [[num line] (indexed (read-lines "foo.txt"))] 
   (println (inc num) line)))

Clojure is a functional language, but not purely functional, so this is pretty easy.

Brian Carper
Almost looks like lisp. Seems like less work than my Haskell answer.
Jon Ericson
Clojure is a Lisp.
Jörg W Mittag
+8  A: 

Ruby

File.readlines(ARGV[1]).each_with_index{|line, index| puts "#{index+1}\t#{line}" }
Colin Curtin
+6  A: 
YenTheFirst
+21  A: 

Commodore 64 BASIC

10 OPEN2,8,2,"0:TESTFILE,S,R"
20 L=1
30 INPUT#2,A$:IF STATUS AND 64 THEN GOTO 50
40 PRINT L "   " A$:L=L+1:GOTO30
50 CLOSE2

Much shorter than VB6.

Steve Hanov
Nice. I was hoping someone would submit an answer that requires line numbers in the source.
Jon Ericson
C64! Now that was a platform. 64K of memory and BASIC burned on the ROM.
Learning
Not to mention it was technically possible to program the drive (1541, 1571, etc) to read the file for you and send you summary results when it was done. The drives had their own CPU, memory, etc so you could program it to run on its own thus freeing up the main CPU for other task.
Andy Webb
Which may have been desirable considering the the drive interface to a standard C64 (w/o fastloading help) was extremely slow. You had (if I recall) a 6502, a whole lot of routines in ROM, and 2K of memory at your disposal.
Andy Webb
+4  A: 

In REBOL:

REBOL []
i: 0
foreach line read/lines %foo.txt [
   print [i: i + 1 line]
   ]
+4  A: 

Fortran 90

This reads lines up to 80 characters long, with the file name supplied on standard input, and closes the file and quits if either an error or EOF is detected.

program read_file
    implicit none
    character(len=80) :: filename
    character(len=80) :: line
    integer           :: lineNumber 

    read(*,*) filename
    open(unit=13, file=filename, status='old', form='formatted')
    lineNumber = 1
    do while (.true.)
        read(13,fmt='(a80)',end=10,err=10) line
        write (*,*) lineNumber, line
        lineNumber = lineNumber + 1
    end do

 10 close(13)
end program read_file
Tim Whitcomb
+8  A: 

English :
From left to right!

<sorry>I couldn't help myself!</sorry>
Eddy
This should be marked as an answer.
Geo
Wanted to write that one.
Martin
+4  A: 

Pointless Haskell

main = interact $ unlines . zipWith ((. ('\t':)) . (++) . show) [1..] . lines

In response to Jon Ericson: lines and unlines are lazy. You can feed an infinite stream into this program, and it will still produce output incrementally.

ephemient
I was actually more worried about unlines. `$ strings /dev/random | runhaskell line_count.hs` confirms your assertion, so I guess I was wrong.
Jon Ericson
Having read through the link, I think I get what's going on in your code. It's quite mind-bending though. (And thank you for posting!)
Jon Ericson
+6  A: 

C# with Linq

This is slightly dirty using the All method as a ForEach to cause the enumeration to occur as ForEach doesn't exist in the BCL, but it's a simple one-liner (formatted onto 3 lines...):

File.ReadAllLines(path)
    .Select((line, index) => string.Format("{0}\t{1}", index, line))
    .All(line => { Console.WriteLine(line); return true; });
Greg Beech
+3  A: 

Objective-C/Cocoa

I tried to keep the program as short as possible, without resorting to any standard C functions.

#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSStringEncoding encoding;
    NSString *input = [NSString stringWithContentsOfFile:@"path_to_file" usedEncoding:&encoding error:nil];
    NSArray *lineArray = [input componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
    int lineNumber = 1;
    for (NSString *line in lineArray) {
        NSString *output = [NSString stringWithFormat:@"%d\t%@\n", lineNumber++, line];
        NSData *outputData = [output dataUsingEncoding:encoding];
        [[NSFileHandle fileHandleWithStandardOutput] writeData:outputData];
    }
    [pool release];
    return 0;
}

Of course, for a large input file, you might improve performance by periodically releasing and recreating the autorelease pool inside of the loop. :-)

benzado
+3  A: 

J

>(4 :'<(>x),>y'/@:,(<@":"0@}.@i.@>:@#,.[)((<@((9{a.),[));.2)1!:1[3)1!:2[4

Seriously. Okay, maybe not so serious about the "your favorite language" part. But serious about it working:

$ jconsole
   >(4 :'<(>x),>y'/@:,(<@":"0@}.@i.@>:@#,.[)((<@((9{a.),[));.2)1!:1[3)1!:2[4
Line the first.
Next line.
End of communication.
^D
1       Line the first.
2       Next line.
3       End of communication.

I'm sure there's shorter ways of writing it -- my brain is simply not up to the challenge.

ephemient
+5  A: 

Common Lisp

Uses the highly unlispy loop macro, but it does make it more compact.

(with-open-file (stream "/this/is/a/file")
  (loop for i from 1
        for line = (read-line stream nil)
        while line do (format t "~D~T~A~&" i line)))

For good measure, a version using the do macro (which is more lispy, as you can tell by the parentheses):

(with-open-file (stream "/this/is/a/file")
  (do ((i 1 (1+ i))
       (line (read-line stream nil)
             (read-line stream nil)))
      ((null line))
    (format t "~D~T~A~&" i line)))

And finally, a (tail) recursive version. For the sake of readability, I've defined the functions globally.

(defun print-enumerated-file (file &optional (init-count 1))
  (with-open-file (stream file)
    (print-enumerated-stream stream init-count)))

(defun print-enumerated-stream (stream &optional (init-count 1))
  (let ((line (read-line stream nil)))
    (when line
      (format t "~D~T~A~&" init-count line)
      (print-enumerated-stream stream (1+ init-count)))))
Sebastian Krog
+3  A: 

SQL Anywhere

create table t ( id int default autoincrement, line long varchar );
load table t ( line ) using file 'file' defaults on;
select id || ' ' || line from t;
Graeme Perrow
+3  A: 

Common Lisp

(defun number-lines (file)
  (with-open-file (stream file)
    (loop for line = (read-line stream nil nil) and line-number from 1
          while line do (format t "~a~a~a~%" line-number #\tab line))))
Rainer Joswig
+8  A: 

C

Without MAX_LINE making people sad. (There's still a max buffer size, but longer lines don't affect output.)

#include <stdio.h>
#include <string.h>
int main() {
    char buf[1024];
    int i = 0, nl = 1;
    while (fgets(buf, sizeof(buf), stdin)) {
        int l = strlen(buf);
        if (nl)
            printf("%d\t%s", ++i, buf);
        else
            fputs(buf, stdout);
        nl = l > 0 && buf[l - 1] == '\n';
    }
    return 0;
}
ephemient
+14  A: 

DailyWTF

  1. Print out file
  2. Put on wooden table
  3. Photograph
  4. Paste into Excel
Martin Beckett
What a cumbersome language!
Jon Ericson
Since it's line-by-line, shouldn't it go: 2a: Use scissors to cut printout into lines; 3: Photograph each line individually; 4: Paste each photo into a cell in Excel?
Anthony Rizk
+1  A: 

CFScript in ColdFusion 8

<cfscript> 
    myfile = FileOpen("c:/text.txt","read");
    while(!FileIsEOF(myfile))
        WriteOutput(FileReadLine(myfile));
    FileClose(myfile);
</cfscript>
Henry
+3  A: 

C#

using (StreamReader reader = new StreamReader(@"c:\MyFile.txt"))
    for (string line; (line = reader.ReadLine()) != null;)
        Console.WriteLine("{0} {1}", (Console.CursorTop + 1).ToString(), line);

Tried a few tricks to keep it compact. :-) [Notice, still disposing Reader and no boxing :-)]

Rui Craveiro
+5  A: 

Lua

local n = 1
for l in io.lines() do
  io.write(n, '\t', l, '\n')
  n = n + 1
end
Norman Ramsey
Out of curiosity, why not write `print (n, '\t', l)`? Is it because print adds spaces?
Jon Ericson
The manual says 'print' provides no guarantees about how values are shown, and that it should be used primarily for debugging. That's how I typically use it.
Norman Ramsey
+10  A: 

awk: (one line version)

{ print NR "\t" $0 }
I'm bringing awk to the top of the answer stack since it's perfectly suited for the job at hand.
Jon Ericson
but wouldn't wc be even better 'wc -l' is designed for counting lines.
Unkwntech
+2  A: 

Java

With all the error checking that should do in this method. If you pass a null String, it chucks a wobbly...

public void printLinesWithNumbers(String filename) throws FileNotFoundException
{
 Scanner sc = null;
 try
 {
  sc = new Scanner(new File(filename));
  int i = 0;
  while(sc.hasNextLine())
   System.out.println(++i + "\t" + sc.nextLine());
 }
 finally
 {
  if(sc != null)
   sc.close();
 }
}
masher
+2  A: 

VB.NET

Dim lines() As String = System.IO.File.ReadAllLines("C:\file.txt")
For i As Integer = 0 To lines.Length - 1
    Console.WriteLine("{0} {1}", (i + 1).ToString, lines(i))
Next
A: 

FORTRAN

OPEN DATA FILE

open (file, FILE='yourDataFile.dat', STATUS='OLD')

READ DATA

read(file,*) n

if (n.GT.nmax) then

    write(*,*) 'Error: n = ', n, 'File is too large'

    goto 9999

endif

LOOP OVER DATA

do 10 i= 1, n

   read(u,100) dataX(i), dataY(i), dataZ(i)

10 enddo
Namadgi
I tried to clean up the formatting of the code, but I could have screwed it up. Also, I think you are missing the part where you print the line number and the line itself.
Jon Ericson
+1  A: 

LPC

This is an ALMOST one line version. I needed a local variable for the line numbering.

int x;
write( implode( map( explode( read_file("/sample.txt"),
   "\n" ), (: (++x) + "\t" + $1 :) ), "\n" ) + "\n" );

And now you know where all my free time went during college.

AHelps
+15  A: 

Sticking to established convention, I will abstain from naming the language used here:

+<,
[
  >[>+>+<<-]>>[<<+>>-]<[->+>+<<]>>[-<<+>>]+++++++++<
  [
    >>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-
  ]
  >>>>[<<<<+>>>>-]<<<[-]<<[->>+>+<<<]>>>[-<<<+>>>]++++++++++++++++++++++++
  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  ++++<
  [
    >>>+<<[>+>[-]<<-]>[<+>-]>
    [
      <<++++++++++++++++++++++++++++++++++++++++++++++++++++
      ++++++++++++++++++++++++++++++++++++++++++++++++>>>+<-
    ]
    <<-<-
  ]
  >>>>[<<<<+>>>>-]<<<[-]++++++++[-<++++++>]<.>++++++++[-<------>]<[->+<]
  >[-<++++++++++>]<[-<->]++++++++[-<++++++>]<.[-]<[>+>+<<-]>>[-<<+>>]
  +++++++++<
  [
    >>>+<<[>+>[-]<<-]>[<+>-]>[<<++++++++++>>>+<-]<<-<-
  ]
  >>>>[<<<<+>>>>-]<<<[-]<[->+<]>[-<++++++++++>]<[-<->]++++++++[-<++++++>]
  <.[-]+++++++++.<+<----------[++++++++++.,----------]++++++++++.[-],
]

Notes:

  • Assumes the implementation makes no change to the cell on EOF, or sets the cell to 0 on EOF.
  • Will currently print all numbers as zero-padded, three-digit numbers.
  • In most implementations of the language, this will only be able to count to 255, at which point it will wrap around and tell you it's on line 0. If your implementation doesn't wrap, get a new one.
  • Most of that code is just printing the current line number as a string. Honestly, I could probably do a lot better if I stored it as a string in the first place. Then I wouldn't have these arbitrary line number wrappings, and it'd be easier to print. And probably a hell of a lot faster.
  • Speaking of which, this program takes 18 seconds to run with my current interpreter (written in Perl, translates source to Perl and eval()s the result) on a 500-line file. My C interpreter is broken at the moment, so I can't give a better benchmark.
  • Also, apparently "200" is printed as "1:0" and "100" as "0:0". "000" (when it wraps) prints just fine, though. I may need to do a little tweaking to figure out what is going on with that, but it's hard to notice while the program is running.

I may, at some point, try to rewrite this a little better. Maybe even with comments!

Chris Lutz
A: 

C#

There's allready an answer up for C#, but when I was tought how to read textfile, I was shown this:

using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
  using(StreamReader sr = new StreamReader(fs))
  {
    while(!sr.EndOfStream)
    {
      list.Add(sr.ReadLine());
    }
  }
}

The 'using" statement automatically implements try/catch, final and close(), which can be usefull but also unwanted. In this case, it's a security measure.

WebDevHobo
I'm no C# programmer, but I don't see where you print the line number.
Jon Ericson
I'm not printing it at all... I'm adding it to an arraylist.If you want to print it, just change "list.Add" into "Console.Writeline"
WebDevHobo
A: 

Delphi

with TFileReader.Create('file') do
try

  while not EOF do
  begin
    WriteLine(IntToStr(Line) + ReadLine);
    Inc(Line);
  end;

finally
  Free;
end
I don't think this prints the line number or the line itself.
Jon Ericson
Additionally the "with" body should be surrounded in a try..finally block to avoid memory leaks.
Romulo A. Ceccon
done and done :)
+2  A: 

F#

path |> System.IO.File.ReadAllLines 
     |> Seq.iteri( fun i l -> printfn "%d\t%s" ( i + 1 ) l )

and if line numbering started at 0 it would be as easy as:

 path |> System.IO.File.ReadAllLines 
      |> Seq.iteri( printfn "%d\t%s" )

I am not a fan of File.ReadAllLines as it returns an array of strings, so we won't get any output before the whole file is read. What we need is a sequence of strings that returns a line as soon as it's read. Something like:

let readlines file = seq {
    use stream = file |> System.IO.File.OpenText
    while not stream.EndOfStream do
       yield stream.ReadLine() 
        }

And then:

path |> readlines     
     |> Seq.iteri( fun i l -> printfn "%d\t%s" ( i + 1 ) l )
Danko Durbić
+1  A: 

Server-side Actionscript 1 for Flash Media Server 3

var file = new File(fileName);
var i = 0;

file.open('text','read');
while (file.isOpen && !file.eof()) trace((++i)+' 'fileile.readln());
file.close();

The output is done in the log file of the application the code is running in and can only be seen by reading that file or in FMS Admin Console. :)

evilpenguin
+3  A: 

D

scope file = new File ("sample.txt");

foreach (ulong n, char[] line; file) {
    writefln ("%d  %s", n, line);
}
Michal Minich
Now _that's_ elegant! Will the "scope" cause the file to be closed?
Robert Fraser
yes, when you declare local variable as scope, its destructor is called when the scope (usually function) finishes (either normally or by exception).
Michal Minich
A: 

Qbasic 1.1

Open "file.txt" for input as #1
do
input #1, pp$
print pp$
loop until (eof(#1))

Simple and easy no?

Omar Abid
I'm pretty sure that does not print the line number.
Jon Ericson
+1  A: 

Ruby

while gets; puts "#{$.}\t#{$_}"; end
Romulo A. Ceccon
+1  A: 

Ruby

ARGF.each_with_index { |line, i| puts "#{i + 1}\t#{line}" }
Romulo A. Ceccon
+1  A: 

Object Pascal

Procedural

var F: Text;
    S: String;
    I: Integer;
begin
  Assign(F, 'file.txt');
  Reset(F);
  I := 0;
  while(not eof(F)) do begin
    ReadLn(F, S);
    WriteLn(IntToStr(I) + #9 + S);
  end;
  Close(F);
end;

Object Oriented

var List: TStringList
begin
  List := TStringList.Create;
  List.LoadFromFile('file.txt');
  for I := 0 to List.Count - 1 do
    WriteLn(IntToStr(I) + #9 + List[I]);
  List.Free;
end;

(I never do the blind "with TSomethingOrOther.Create do" things, except when toying with game design.)

The Wicked Flea
For those who don't know it, Object Pascal doesn't have escaped characters beyond quotes; therefore a tab must be inserted via ascii code: #9. I wish I could "tag" my code with a language for better highlighting.
The Wicked Flea
+3  A: 

Scala

var lineNumber = 1
for (line <- Source.fromFile("file.txt").getLines) {
    println(lineNumber + "\t" + line)
    lineNumber += 1
}
jrcalzada
Functional alternative: http://stackoverflow.com/questions/678684/how-do-you-read-a-file-line-by-line-in-your-language-of-choice/2870623#2870623
missingfaktor
A: 

erlang

{ok, FD} = file:open("filename", [read]),
readall(FD),
close(FD).

readall(FD) ->
   readall(FD,[]).

readall(FD,eof) ->
   [];
readall(FD,{error,_}) ->
   [];
readall(FD,_) ->
   Data = io:get_line(FD),
   io:format("~s~n",[Data]),
   readall(FD,Data).
Richard
+1  A: 

Nemerle

Imperative style:

using System.IO.File;
using System.Console;

def ReadFileLineByLine(path)
{
    using (reader = OpenText(path))
    {
     mutable lineNumber = 1;
     while (!reader.EndOfStream)
     {
      WriteLine($"$lineNumber $(reader.ReadLine())");
      ++lineNumber;
     }
    }
}

ReadFileLineByLine("test.txt");

Functional style:

using Nemerle.Utility;
using System.IO.File;
using System.Console;

ReadAllLines("test.txt").IterI((n, line) => WriteLine($"$(n+1) $line"));
Don Reba
A: 

VBScript

Const ForReading = 1
Dim oFSO, oFile, i

Set oFSO  = CreateObject("Scripting.FileSystemObject")
Set oFile = oFSO.OpenTextFile(strFileName, ForReading)

i = 1
While Not oFile.AtEndOfStream
  WScript.Echo  i & vbTab & oFile.ReadLine
  i = i + 1
Wend

oFile.Close
Helen
A: 

Windows Batch File

@echo off
setlocal enableextensions enabledelayedexpansion

for /f "delims=" %%s in (file.txt) do (
  @echo !i! %%s
  set /a i += 1
)
Helen
A: 

Scala 2.8 RC1:

Source.fromPath("Hello.txt").getLines().zipWithIndex foreach {
  case(line, index) ⇒ println("%4d\t%s" format (index + 1, line))
}
missingfaktor