Read a file line by line: Difference between revisions
Puppydrum64 (talk | contribs) |
Puppydrum64 (talk | contribs) |
||
Line 2,453:
!:LineCount = !.LineCount + 1,
io.format("%d: %s", [i(!.LineCount), s(Line)], !IO).</lang>
=={{header|Neko}}==
|
Revision as of 00:31, 21 July 2022
You are encouraged to solve this task according to the task description, using any language you may know.
Read a file one line at a time, as opposed to reading the entire file at once.
- Related tasks
360 Assembly
This program uses OS QSAM I/O macros (OPEN,CLOSE,GET,PUT,DCB). <lang 360asm>* Read a file line by line 12/06/2016 READFILE CSECT
SAVE (14,12) save registers on entry PRINT NOGEN BALR R12,0 establish addressability USING *,R12 set base register ST R13,SAVEA+4 link mySA->prevSA LA R11,SAVEA mySA ST R11,8(R13) link prevSA->mySA LR R13,R11 set mySA pointer OPEN (INDCB,INPUT) open the input file OPEN (OUTDCB,OUTPUT) open the output file
LOOP GET INDCB,PG read record
CLI EOFFLAG,C'Y' eof reached? BE EOF PUT OUTDCB,PG write record B LOOP
EOF CLOSE (INDCB) close input
CLOSE (OUTDCB) close output L R13,SAVEA+4 previous save area addrs RETURN (14,12),RC=0 return to caller with rc=0
INEOF CNOP 0,4 end-of-data routine
MVI EOFFLAG,C'Y' set the end-of-file flag BR R14 return to caller
SAVEA DS 18F save area for chaining INDCB DCB DSORG=PS,MACRF=PM,DDNAME=INDD,LRECL=80, *
RECFM=FB,EODAD=INEOF
OUTDCB DCB DSORG=PS,MACRF=PM,DDNAME=OUTDD,LRECL=80, *
RECFM=FB
EOFFLAG DC C'N' end-of-file flag PG DS CL80 buffer
YREGS END READFILE</lang>
8th
<lang forth> "path/to/file" f:open ( . cr ) f:eachline f:close </lang>
AArch64 Assembly
<lang AArch64 Assembly> /* ARM assembly AARCH64 Raspberry PI 3B */ /* program readfile64.s */
/*******************************************/ /* Constantes file */ /*******************************************/ /* for this file see task include a file in language AArch64 assembly*/ .include "../includeConstantesARM64.inc"
.equ BUFFERSIZE, 1000 .equ LINESIZE, 100
/*******************************************/
/* Structures */
/********************************************/
/* structure read file*/
.struct 0
readfile_Fd: // File descriptor
.struct readfile_Fd + 8
readfile_buffer: // read buffer
.struct readfile_buffer + 8
readfile_buffersize: // buffer size
.struct readfile_buffersize + 8
readfile_line: // line buffer
.struct readfile_line + 8
readfile_linesize: // line buffer size
.struct readfile_linesize + 8
readfile_pointer:
.struct readfile_pointer + 8 // read pointer (init to buffer size + 1)
readfile_end: /*******************************************/ /* Initialized data */ /*******************************************/ .data szFileName: .asciz "fictest.txt" szCarriageReturn: .asciz "\n" /* datas error display */ szMessError: .asciz "Error detected : @ \n"
/*******************************************/ /* UnInitialized data */ /*******************************************/ .bss sBuffer: .skip BUFFERSIZE // buffer result szLineBuffer: .skip LINESIZE .align 4 stReadFile: .skip readfile_end sZoneConv: .skip 24 /*******************************************/ /* code section */ /*******************************************/ .text .global main main:
mov x0,AT_FDCWD ldr x1,qAdrszFileName // File name mov x2,O_RDWR // flags mov x3,0 // mode mov x8,OPEN // open file svc 0 cmp x0,0 // error ? ble error ldr x21,qAdrstReadFile // init struture readfile str x0,[x21,readfile_Fd] // save FD in structure ldr x0,qAdrsBuffer // buffer address str x0,[x21,readfile_buffer] mov x0,BUFFERSIZE // buffer size str x0,[x21,readfile_buffersize] ldr x0,qAdrszLineBuffer // line buffer address str x0,[x21,readfile_line] mov x0,LINESIZE // line buffer size str x0,[x21,readfile_linesize] mov x0,BUFFERSIZE + 1 // init read pointer str x0,[x21,readfile_pointer]
1: // begin read loop
mov x0,x21 bl readLineFile cmp x0,0 beq end // end loop blt error ldr x0,qAdrszLineBuffer // display line bl affichageMess ldr x0,qAdrszCarriageReturn // display line return bl affichageMess b 1b // and loop
end:
ldr x1,qAdrstReadFile ldr x0,[x1,readfile_Fd] // load FD to structure mov x8,CLOSE // call system close file svc 0 cmp x0,0 blt error mov x0,0 // return code b 100f
error:
ldr x1,qAdrsZoneConv bl conversion10S ldr x0,qAdrszMessError // error message ldr x1,qAdrsZoneConv bl strInsertAtCharInc // insert result at @ character bl affichageMess mov x0,1 // return error code
100: // standard end of the program
mov x8,EXIT // request to exit program svc 0 // perform system call
qAdrsBuffer: .quad sBuffer qAdrszFileName: .quad szFileName qAdrszMessError: .quad szMessError qAdrsZoneConv: .quad sZoneConv qAdrszCarriageReturn: .quad szCarriageReturn qAdrstReadFile: .quad stReadFile qAdrszLineBuffer: .quad szLineBuffer /******************************************************************/ /* sub strings index start number of characters */ /******************************************************************/ /* x0 contains the address of the structure */ /* x0 returns number of characters or -1 if error */ readLineFile:
stp x1,lr,[sp,-16]! // save registers mov x14,x0 // save structure ldr x11,[x14,#readfile_buffer] ldr x12,[x14,#readfile_buffersize] ldr x15,[x14,#readfile_pointer] ldr x16,[x14,#readfile_linesize] ldr x18,[x14,#readfile_buffersize] ldr x10,[x14,#readfile_line] mov x13,0 strb wzr,[x10,x13] // store zéro in line buffer cmp x15,x12 // pointer buffer < buffer size ? ble 2f // no file read
1: // loop read file
ldr x0,[x14,#readfile_Fd] mov x1,x11 // buffer address mov x2,x12 // buffer size mov x8,READ // call system read file svc 0 cmp x0,#0 // error read or end ? ble 100f mov x18,x0 // number of read characters mov x15,#0 // init buffer pointer
2: // begin loop copy characters
ldrb w0,[x11,x15] // load 1 character read buffer cmp x0,0x0A // end line ? beq 4f strb w0,[x10,x13] // store character in line buffer add x13,x13,1 // increment pointer line cmp x13,x16 bgt 99f // error add x15,x15,1 // increment buffer pointer cmp x15,x12 // end buffer ? bge 1b // yes new read cmp x15,x18 // read characters ? blt 2b // no loop // final cmp x13,0 // no characters in line buffer ? beq 100f
4:
strb wzr,[x10,x13] // store zéro final add x15,x15,#1 str x15,[x14,#readfile_pointer] // store pointer in structure str x18,[x14,#readfile_buffersize] // store number of last characters mov x0,x13 // return length of line b 100f
99:
mov x0,#-2 // line buffer too small -> error
100:
ldp x1,lr,[sp],16 // restaur 2 registers ret // return to address lr x30
/********************************************************/ /* File Include fonctions */ /********************************************************/ /* for this file see task include a file in language AArch64 assembly */ .include "../includeARM64.inc" </lang>
Action!
<lang>char array TXT
Proc Main()
Open (1,"D:FILENAME.TXT",4,0) Do InputSD(1,TXT) PrintE(TXT) Until EOF(1) Od Close(1)
Return </lang>
Ada
line_by_line.adb: <lang Ada>with Ada.Text_IO; use Ada.Text_IO;
procedure Line_By_Line is
File : File_Type;
begin
Open (File => File, Mode => In_File, Name => "line_by_line.adb"); While not End_Of_File (File) Loop Put_Line (Get_Line (File)); end loop;
Close (File);
end Line_By_Line; </lang>
- Output:
with Ada.Text_IO; use Ada.Text_IO; procedure Line_By_Line is File : File_Type; begin Open (File => File, Mode => In_File, Name => "line_by_line.adb"); While not End_Of_File (File) Loop Put_Line (Get_Line (File)); end loop; Close (File); end Line_By_Line;
Aime
<lang aime>file f; text s;
f.affix("src/aime.c");
while (f.line(s) != -1) {
o_text(s); o_byte('\n');
}</lang>
ALGOL 68
File: ./Read_a_file_line_by_line.a68<lang algol68>#!/usr/local/bin/a68g --script #
FILE foobar; INT errno = open(foobar, "Read_a_file_line_by_line.a68", stand in channel);
STRING line; FORMAT line fmt = $gl$;
PROC mount next tape = (REF FILE file)BOOL: (
print("Please mount next tape or q to quit"); IF read char = "q" THEN done ELSE TRUE FI
);
on physical file end(foobar, mount next tape); on logical file end(foobar, (REF FILE skip)BOOL: done);
FOR count DO
getf(foobar, (line fmt, line)); printf(($g(0)": "$, count, line fmt, line))
OD; done: SKIP</lang>
- Output:
1: #!/usr/local/bin/a68g --script # 2: 3: FILE foobar; 4: INT errno = open(foobar, "Read_a_file_line_by_line.a68", stand in channel); 5: 6: STRING line; 7: FORMAT line fmt = $gl$; 8: 9: PROC mount next tape = (REF FILE file)BOOL: ( 10: print("Please mount next tape or q to quit"); 11: IF read char = "q" THEN done ELSE TRUE FI 12: ); 13: 14: on physical file end(foobar, mount next tape); 15: on logical file end(foobar, (REF FILE skip)BOOL: done); 16: 17: FOR count DO 18: getf(foobar, (line fmt, line)); 19: printf(($g(0)": "$, count, line fmt, line)) 20: OD; 21: done: SKIP
APL
<lang APL> ⍝⍝ GNU APL Version ∇listFile fname ;fileHandle;maxLineLen;line
maxLineLen ← 128 fileHandle ← ⎕FIO['fopen'] fname
readLoop:
→(0=⍴(line ← maxLineLen ⎕FIO['fgets'] fileHandle))/eof ⍞ ← ⎕AV[1+line] ⍝⍝ bytes to ASCII → readLoop
eof:
⊣⎕FIO['fclose'] fileHandle ⊣⎕FIO['errno'] fileHandle
∇
listFile 'corpus/sample1.txt'
This is some sample text. The text itself has multiple lines, and the text has some words that occur multiple times in the text.
This is the end of the text.
</lang>
Amazing Hopper
<lang Amazing Hopper>
- include <hopper.h>
main:
.ctrlc fd=0 fopen(OPEN_READ,"archivo.txt")(fd) if file error? {"Error open file: "},file error else line read=0 while( not(feof(fd))) fread line(1000)(fd), ++line read println wend {"Total read lines : ",line read} fclose(fd) endif println
exit(0) </lang>
- Output:
RX/RY,A,B,C,D,E,F,G,H,I,J fila 1,1,2,3,4,5,6,7.998,8,9.034,10 fila 2,10,20,30,40,50,60,70,80,90,100 fila 3,100,200,300.5,400,500,600,700,800,900,1000 fila 4,5,10,15,20,25,30,35,40,45,50 fila 5,a,b,c,d,e,f,g,h,i,j fila 6,1,2,3,4,5,6,7,8,9,10 Total read lines : 7
ARM Assembly
<lang ARM Assembly> /* ARM assembly Raspberry PI */ /* program readfile.s */
/* Constantes */ .equ STDOUT, 1 @ Linux output console .equ EXIT, 1 @ Linux syscall .equ READ, 3 .equ WRITE, 4 .equ OPEN, 5 .equ CLOSE, 6
.equ O_RDWR, 0x0002 @ open for reading and writing
.equ BUFFERSIZE, 100 .equ LINESIZE, 100
/*******************************************/ /* Structures */ /********************************************/ /* structure read file*/
.struct 0
readfile_Fd: @ File descriptor
.struct readfile_Fd + 4
readfile_buffer: @ read buffer
.struct readfile_buffer + 4
readfile_buffersize: @ buffer size
.struct readfile_buffersize + 4
readfile_line: @ line buffer
.struct readfile_line + 4
readfile_linesize: @ line buffer size
.struct readfile_linesize + 4
readfile_pointer:
.struct readfile_pointer + 4 @ read pointer (init to buffer size + 1)
readfile_end: /* Initialized data */ .data szFileName: .asciz "fictest.txt" szCarriageReturn: .asciz "\n" /* datas error display */ szMessErreur: .asciz "Error detected.\n" szMessErr: .ascii "Error code hexa : " sHexa: .space 9,' '
.ascii " decimal : "
sDeci: .space 15,' '
.asciz "\n"
/* UnInitialized data */ .bss sBuffer: .skip BUFFERSIZE @ buffer result szLineBuffer: .skip LINESIZE .align 4 stReadFile: .skip readfile_end
/* code section */ .text .global main main:
ldr r0,iAdrszFileName @ File name mov r1,#O_RDWR @ flags mov r2,#0 @ mode mov r7,#OPEN @ open file svc #0 cmp r0,#0 @ error ? ble error ldr r1,iAdrstReadFile @ init struture readfile str r0,[r1,#readfile_Fd] @ save FD in structure ldr r0,iAdrsBuffer @ buffer address str r0,[r1,#readfile_buffer] mov r0,#BUFFERSIZE @ buffer size str r0,[r1,#readfile_buffersize] ldr r0,iAdrszLineBuffer @ line buffer address str r0,[r1,#readfile_line] mov r0,#LINESIZE @ line buffer size str r0,[r1,#readfile_linesize] mov r0,#BUFFERSIZE + 1 @ init read pointer str r0,[r1,#readfile_pointer]
1: @ begin read loop
mov r0,r1 bl readLineFile cmp r0,#0 beq end @ end loop blt error
ldr r0,iAdrszLineBuffer @ display line bl affichageMess ldr r0,iAdrszCarriageReturn @ display line return bl affichageMess b 1b @ and loop
end:
ldr r1,iAdrstReadFile ldr r0,[r1,#readfile_Fd] @ load FD to structure mov r7, #CLOSE @ call system close file svc #0 cmp r0,#0 blt error mov r0,#0 @ return code b 100f
error:
ldr r1,iAdrszMessErreur @ error message bl displayError mov r0,#1 @ return error code
100: @ standard end of the program
mov r7, #EXIT @ request to exit program svc 0 @ perform system call
iAdrsBuffer: .int sBuffer iAdrszFileName: .int szFileName iAdrszMessErreur: .int szMessErreur iAdrszCarriageReturn: .int szCarriageReturn iAdrstReadFile: .int stReadFile iAdrszLineBuffer: .int szLineBuffer /******************************************************************/ /* sub strings index start number of characters */ /******************************************************************/ /* r0 contains the address of the structure */ /* r0 returns number of characters or -1 if error */ readLineFile:
push {r1-r8,lr} @ save registers mov r4,r0 @ save structure ldr r1,[r4,#readfile_buffer] ldr r2,[r4,#readfile_buffersize] ldr r5,[r4,#readfile_pointer] ldr r6,[r4,#readfile_linesize] ldr r7,[r4,#readfile_buffersize] ldr r8,[r4,#readfile_line] mov r3,#0 @ line pointer strb r3,[r8,r3] @ store zéro in line buffer cmp r5,r2 @ pointer buffer < buffer size ? ble 2f @ no file read
1: @ loop read file
ldr r0,[r4,#readfile_Fd] mov r7,#READ @ call system read file svc 0 cmp r0,#0 @ error read or end ? ble 100f mov r7,r0 @ number of read characters mov r5,#0 @ init buffer pointer
2: @ begin loop copy characters
ldrb r0,[r1,r5] @ load 1 character read buffer cmp r0,#0x0A @ end line ? beq 4f strb r0,[r8,r3] @ store character in line buffer add r3,#1 @ increment pointer line cmp r3,r6 movgt r0,#-2 @ line buffer too small -> error bgt 100f add r5,#1 @ increment buffer pointer cmp r5,r2 @ end buffer ? bge 1b @ yes new read cmp r5,r7 @ read characters ? blt 2b @ no loop @ final cmp r3,#0 @ no characters in line buffer ? beq 100f
4:
mov r0,#0 strb r0,[r8,r3] @ store zéro final add r5,#1 str r5,[r4,#readfile_pointer] @ store pointer in structure str r7,[r4,#readfile_buffersize] @ store number of last characters mov r0,r3 @ return length of line
100:
pop {r1-r8,lr} @ restaur registers bx lr @ return
/******************************************************************/ /* display text with size calculation */ /******************************************************************/ /* r0 contains the address of the message */ affichageMess:
push {r0,r1,r2,r7,lr} @ save registers mov r2,#0 @ counter length */
1: @ loop length calculation
ldrb r1,[r0,r2] @ read octet start position + index cmp r1,#0 @ if 0 its over addne r2,r2,#1 @ else add 1 in the length bne 1b @ and loop @ so here r2 contains the length of the message mov r1,r0 @ address message in r1 mov r0,#STDOUT @ code to write to the standard output Linux mov r7, #WRITE @ code call system "write" svc #0 @ call system pop {r0,r1,r2,r7,lr} @ restaur registers bx lr @ return
/***************************************************/ /* display error message */ /***************************************************/ /* r0 contains error code r1 : message address */ displayError:
push {r0-r2,lr} @ save registers mov r2,r0 @ save error code mov r0,r1 bl affichageMess mov r0,r2 @ error code ldr r1,iAdrsHexa bl conversion16 @ conversion hexa mov r0,r2 @ error code ldr r1,iAdrsDeci @ result address bl conversion10S @ conversion decimale ldr r0,iAdrszMessErr @ display error message bl affichageMess
100:
pop {r0-r2,lr} @ restaur registers bx lr @ return
iAdrszMessErr: .int szMessErr iAdrsHexa: .int sHexa iAdrsDeci: .int sDeci /******************************************************************/ /* Converting a register to hexadecimal */ /******************************************************************/ /* r0 contains value and r1 address area */ conversion16:
push {r1-r4,lr} @ save registers mov r2,#28 @ start bit position mov r4,#0xF0000000 @ mask mov r3,r0 @ save entry value
1: @ start loop
and r0,r3,r4 @ value register and mask lsr r0,r2 @ move right cmp r0,#10 @ compare value addlt r0,#48 @ <10 ->digit addge r0,#55 @ >10 ->letter A-F strb r0,[r1],#1 @ store digit on area and + 1 in area address lsr r4,#4 @ shift mask 4 positions subs r2,#4 @ counter bits - 4 <= zero ? bge 1b @ no -> loop
100:
pop {r1-r4,lr} @ restaur registers bx lr
/***************************************************/ /* Converting a register to a signed decimal */ /***************************************************/ /* r0 contains value and r1 area address */ conversion10S:
push {r0-r4,lr} @ save registers mov r2,r1 @ debut zone stockage mov r3,#'+' @ par defaut le signe est + cmp r0,#0 @ negative number ? movlt r3,#'-' @ yes mvnlt r0,r0 @ number inversion addlt r0,#1 mov r4,#10 @ length area
1: @ start loop
bl divisionpar10U add r1,#48 @ digit strb r1,[r2,r4] @ store digit on area sub r4,r4,#1 @ previous position cmp r0,#0 @ stop if quotient = 0 bne 1b
strb r3,[r2,r4] @ store signe subs r4,r4,#1 @ previous position blt 100f @ if r4 < 0 -> end
mov r1,#' ' @ space
2:
strb r1,[r2,r4] @store byte space subs r4,r4,#1 @ previous position bge 2b @ loop if r4 > 0
100:
pop {r0-r4,lr} @ restaur registers bx lr
/***************************************************/ /* division par 10 unsigned */ /***************************************************/ /* r0 dividende */ /* r0 quotient */ /* r1 remainder */ divisionpar10U:
push {r2,r3,r4, lr} mov r4,r0 @ save value //mov r3,#0xCCCD @ r3 <- magic_number lower raspberry 3 //movt r3,#0xCCCC @ r3 <- magic_number higter raspberry 3 ldr r3,iMagicNumber @ r3 <- magic_number raspberry 1 2 umull r1, r2, r3, r0 @ r1<- Lower32Bits(r1*r0) r2<- Upper32Bits(r1*r0) mov r0, r2, LSR #3 @ r2 <- r2 >> shift 3 add r2,r0,r0, lsl #2 @ r2 <- r0 * 5 sub r1,r4,r2, lsl #1 @ r1 <- r4 - (r2 * 2) = r4 - (r0 * 10) pop {r2,r3,r4,lr} bx lr @ leave function
iMagicNumber: .int 0xCCCCCCCD
</lang>
Astro
<lang python>for line in lines open('input.txt'):
print line
</lang>
AutoHotkey
<lang AutoHotkey>; --> Prompt the user to select the file being read
FileSelectFile, File, 1, %A_ScriptDir%, Select the (text) file to read, Documents (*.txt) ; Could of course be set to support other filetypes If Errorlevel ; If no file selected ExitApp
- --> Main loop
- Input (File), Output (Text)
Loop { FileReadLine, Line, %File%, %A_Index% ; Reads line N (where N is loop iteration) if Errorlevel ; If line does not exist, break loop break Text .= A_Index ". " Line . "`n" ; Appends the line to the variable "Text", adding line number before & new line after }
- --> Delivers the output as a text file
FileDelete, Output.txt ; Makes sure output is clear before writing FileAppend, %Text%, Output.txt ; Writes the result to Output.txt Run Output.txt ; Shows the created file</lang>
AWK
Reading files line-by-line is the standard operation of awk.
One-liner: <lang AWK>awk '{ print $0 }' filename</lang>
Shorter:
Printing the input is the default-action for matching lines,
and "1" evaluates to "True",
so this is the shortest possible awk-program
(not counting the Empty program):
<lang AWK>awk '1' filename</lang>
Longer:
Reading several files, with some processing:
<lang AWK># usage: awk -f readlines.awk *.txt
BEGIN { print "# Reading..." }
FNR==1 { f++; print "# File #" f, ":", FILENAME }
/^#/ { c++; next } # skip lines starting with "#", but count them
/you/ { gsub("to", "TO") } # change text in lines with "you" somewhere
/TO/ { print FNR,":",$0; next } # print with line-number
{ print } # same as "print $0"
END { print "# Done with", f, "file(s), with a total of", NR, "lines." } END { print "# Comment-lines:", c }</lang> Note:
- The variables c and f are initialized automatically to 0
- NR is the number of records read so far, for all files read
- FNR is the number of records read from the current file
- There can be multiple BEGIN and END-blocks
- Input:
# This is the file input.txt you can use it to provide input to your program to do some processing.
- Output:
# Reading... # File #1 : input.txt you can use it to provide input 4 : TO your program TO do some processing. # Done with 1 file(s), with a total of 5 lines. # Comment-lines: 1
BASIC
BaCon
<lang freebasic>' Read a file line by line filename$ = "readlines.bac" OPEN filename$ FOR READING AS fh READLN fl$ FROM fh WHILE ISFALSE(ENDFILE(fh))
INCR lines READLN fl$ FROM fh
WEND PRINT lines, " lines in ", filename$ CLOSE FILE fh</lang>
- Output:
prompt$ ./readlines 10 lines in readlines.bac
IS-BASIC
<lang IS-BASIC>100 INPUT PROMPT "Filename: ":NAME$ 110 OPEN #1:NAME$ ACCESS INPUT 120 COPY FROM #1 TO #0 130 CLOSE #1</lang>
Locomotive Basic
<lang locobasic>10 OPENIN"foo.txt" 20 WHILE NOT EOF 30 LINE INPUT#9,i$ 40 PRINT i$ 50 WEND</lang>
OxygenBasic
The core function GetFile reads the whole file: <lang oxygenbasic> function getline(string s, int *i) as string
int sl=i, el=i byte b at strptr(s) do select b[el] case 0 i=el+1 : exit do case 10 'lf i=el+1 : exit do case 13 'cr i=el+1 if b[i]=10 then i++ 'crlf exit do end select el++ loop return mid(s,sl,el-sl)
end function
'read all file lines '===================
string s=getfile "t.txt" int le=len(s) int i=1 int c=0 string wr if le=0 then goto done do
wr = getline(s,i) 'print wr c++ if i>le then exit do
end do done: print "Line count " c </lang>
QBasic
<lang qbasic>f = FREEFILE filename$ = "file.txt"
OPEN filename$ FOR INPUT AS #f
WHILE NOT EOF(f)
LINE INPUT #f, linea$ PRINT linea$
WEND CLOSE #f END</lang>
uBasic/4tH
uBasic/4tH only supports text files - and they can only be read line by line. READ() fills the line buffer. In order to pass (parts of) the line to a variable or function, the tokenizer function TOK() needs to be called with a specific delimiter. In order to parse the entire line in one go, the string terminator CHR(0) must be provided. <lang>If Set (a, Open ("myfile.bas", "r")) < 0 Then Print "Cannot open \qmyfile.bas\q" : End
Do While Read (a)
Print Show(Tok(0))
Loop
Close a </lang>
ZX Spectrum Basic
The tape recorder interface does not support fragmented reads, because tape recorder start and stop is not atomic, (and a leadin is required for tape input). However, the microdrive does support fragmented reads. In the following example, we read a file line by line from a file on microdrive 1.
<lang basic>10 REM open my file for input 20 OPEN #4;"m";1;"MYFILE": REM stream 4 is the first available for general purpose 30 INPUT #4; LINE a$: REM a$ will hold our line from the file 40 REM because we do not know how many lines are in the file, we need an error trap 50 REM to gracefully exit when the file is read. (omitted from this example) 60 REM to prevent an error at end of file, place a handler here 100 GOTO 30</lang>
BASIC256
<lang BASIC256>f = freefile filename$ = "file.txt"
open f, filename$
while not eof(f)
print readline(f)
end while close f end</lang>
Batch File
This takes account on the blank lines, because FOR ignores blank lines when reading a file. <lang dos>@echo off rem delayed expansion must be disabled before the FOR command. setlocal disabledelayedexpansion for /f "tokens=1* delims=]" %%A in ('type "File.txt"^|find /v /n ""') do ( set var=%%B setlocal enabledelayedexpansion echo(!var! endlocal )</lang>
BBC BASIC
This method is appropriate if the lines are terminated by a single CR or LF: <lang bbcbasic> file% = OPENIN("*.txt")
IF file%=0 ERROR 100, "File could not be opened" WHILE NOT EOF#file% a$ = GET$#file% ENDWHILE CLOSE #file%</lang>
This method is appropriate if the lines are terminated by a CRLF pair: <lang bbcbasic> file% = OPENIN("*.txt")
IF file%=0 ERROR 100, "File could not be opened" WHILE NOT EOF#file% INPUT #file%, a$ IF ASCa$=10 a$ = MID$(a$,2) ENDWHILE CLOSE #file%</lang>
Bracmat
fil
is a relatively low level Bracmat function for manipulating files. Depending on the parameters it opens, closes, reads, writes a file or reads or sets the file position.
<lang bracmat> fil$("test.txt",r) { r opens a text file, rb opens a binary file for reading }
& fil$(,STR,\n) { first argument empty: same as before (i.e. "test.txt") }
{ if \n were replaced by e.g. "\n\t " we would read word-wise instead }
& 0:?lineno & whl
' ( fil$:(?line.?sep) { "sep" contains found stop character, i.e. \n } & put$(line (1+!lineno:?lineno) ":" !line \n) )
& (fil$(,SET,-1)|); { Setting file position before start closes file, and fails.
Therefore the | }</lang>
Brat
<lang brat>include :file
file.each_line "foobar.txt" { line |
p line
}</lang>
C
<lang c>/* Programa: Número mayor de tres números introducidos (Solución 1) */
- include <conio.h>
- include <stdio.h>
int main() {
int n1, n2, n3;
printf( "\n Introduzca el primer n%cmero (entero): ", 163 ); scanf( "%d", &n1 ); printf( "\n Introduzca el segundo n%cmero (entero): ", 163 ); scanf( "%d", &n2 ); printf( "\n Introduzca el tercer n%cmero (entero): ", 163 ); scanf( "%d", &n3 );
if ( n1 >= n2 && n1 >= n3 ) printf( "\n %d es el mayor.", n1 ); else
if ( n2 > n3 ) printf( "\n %d es el mayor.", n2 ); else printf( "\n %d es el mayor.", n3 ); getch(); /* Pausa */
return 0;
}</lang>
with getline
<lang C>// From manpage for "getline"
- include <stdio.h>
- include <stdlib.h>
int main(void) { FILE *stream; char *line = NULL; size_t len = 0; ssize_t read;
stream = fopen("file.txt", "r"); if (stream == NULL) exit(EXIT_FAILURE);
while ((read = getline(&line, &len, stream)) != -1) { printf("Retrieved line of length %u :\n", read); printf("%s", line); }
free(line); fclose(stream); exit(EXIT_SUCCESS); }</lang>
Using mmap()
Implementation using mmap syscall. Works on Linux 2.6.* and on *BSDs. Line reading routine takes a callback function, each line is passed into callback as begin and end pointer. Let OS handle your memory pages, we don't need no stinking mallocs. <lang C>#include <stdio.h>
- include <sys/types.h>
- include <sys/stat.h>
- include <fcntl.h> /* C POSIX library file control options */
- include <unistd.h> /* C POSIX library system calls: open, close */
- include <sys/mman.h> /* memory management declarations: mmap, munmap */
- include <errno.h> /* Std C library system error numbers: errno */
- include <err.h> /* GNU C lib error messages: err */
int read_lines(const char * fname, int (*call_back)(const char*, const char*)) {
int fd = open(fname, O_RDONLY); struct stat fs; char *buf, *buf_end; char *begin, *end, c;
if (fd == -1) { err(1, "open: %s", fname); return 0; }
if (fstat(fd, &fs) == -1) { err(1, "stat: %s", fname); return 0; }
/* fs.st_size could have been 0 actually */ buf = mmap(0, fs.st_size, PROT_READ, MAP_SHARED, fd, 0); if (buf == (void*) -1) { err(1, "mmap: %s", fname); close(fd); return 0; }
buf_end = buf + fs.st_size;
begin = end = buf; while (1) { if (! (*end == '\r' || *end == '\n')) { if (++end < buf_end) continue; } else if (1 + end < buf_end) { /* see if we got "\r\n" or "\n\r" here */ c = *(1 + end); if ( (c == '\r' || c == '\n') && c != *end) ++end; }
/* call the call back and check error indication. Announce error here, because we didn't tell call_back the file name */ if (! call_back(begin, end)) { err(1, "[callback] %s", fname); break; }
if ((begin = ++end) >= buf_end) break; }
munmap(buf, fs.st_size); close(fd); return 1;
}
int print_line(const char* begin, const char* end) {
if (write(fileno(stdout), begin, end - begin + 1) == -1) { return 0; } return 1;
}
int main() {
return read_lines("test.ps", print_line) ? 0 : 1;
} </lang>
C#
'File.ReadLines' reads the lines of a file which could easily be stepped through. <lang csharp>foreach (string readLine in File.ReadLines("FileName"))
DoSomething(readLine);</lang>
A full code may look like; <lang csharp>using System; using System.IO; using System.Text;
namespace RosettaCode {
internal class Program { private static void Main() { var sb = new StringBuilder(); string F = "File.txt";
// Read a file, line by line. try { foreach (string readLine in File.ReadLines(F)) { // Use the data in some way... sb.Append(readLine); sb.Append("\n"); } } catch (Exception exception) { Console.WriteLine(exception.Message); Environment.Exit(1); }
// Preset the results Console.WriteLine(sb.ToString()); } }
}</lang>
C++
<lang cpp>#include <fstream>
- include <string>
- include <iostream>
int main( int argc , char** argv ) {
int linecount = 0 ; std::string line ; std::ifstream infile( argv[ 1 ] ) ; // input file stream if ( infile ) { while ( getline( infile , line ) ) {
std::cout << linecount << ": "
<< line << '\n' ; //supposing '\n' to be line end
linecount++ ;
} } infile.close( ) ; return 0 ;
}</lang>
using std::getline
"thefile.txt" 888 4432 100 -25 doggie
<lang cpp>
- include <fstream>
- include <iostream>
- include <sstream>
- include <string>
int main() {
std::ifstream infile("thefile.txt"); std::string line; while (std::getline(infile, line) ) { std::istringstream iss(line); int a, b; if (!(iss >> a >> b)) { break; } // if no error a and b get values from file
std::cout << "a:\t" << a <<"\n"; std::cout << "b:\t" << b <<"\n"; } std::cout << "finished" << std::endl;
}</lang>
- Output:
a: 888 b: 4432 a: 100 b: -25 finished
<lang cpp>#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN { FileIn in(CommandLine()[0]); while(in && !in.IsEof()) Cout().PutLine(in.GetLine()); }</lang>
Clojure
<lang Clojure> (with-open [r (clojure.java.io/reader "some-file.txt")]
(doseq [l (line-seq r)] (println l)))
</lang>
CLU
<lang clu>start_up = proc ()
po: stream := stream$primary_output() % There is a special type for file names. This ensures that % the path is valid; if not, file_name$parse would throw an % exception (which we are just ignoring here). fname: file_name := file_name$parse("input.txt") % File I/O is then done through a stream just like any I/O. % If the file were not accessible, stream$open would throw an % exception. fstream: stream := stream$open(fname, "read") count: int := 0 % count the lines while true do % Read a line. This will end the loop once the end is reached, % as the exception handler is outside the loop. line: string := stream$getl(fstream) % Show the line count := count + 1 stream$putl(po, int$unparse(count) || ": " || line) end except when end_of_file: % Close the file once we're done stream$close(fstream) end
end start_up</lang>
COBOL
<lang cobol> IDENTIFICATION DIVISION.
PROGRAM-ID. read-file-line-by-line.
ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT input-file ASSIGN TO "input.txt" ORGANIZATION LINE SEQUENTIAL FILE STATUS input-file-status.
DATA DIVISION. FILE SECTION. FD input-file. 01 input-record PIC X(256).
WORKING-STORAGE SECTION. 01 input-file-status PIC 99. 88 file-is-ok VALUE 0. 88 end-of-file VALUE 10.
01 line-count PIC 9(6).
PROCEDURE DIVISION. OPEN INPUT input-file IF NOT file-is-ok DISPLAY "The file could not be opened." GOBACK END-IF
PERFORM VARYING line-count FROM 1 BY 1 UNTIL end-of-file READ input-file DISPLAY line-count ": " FUNCTION TRIM(input-record) END-PERFORM
CLOSE input-file
GOBACK .</lang>
CoffeeScript
<lang coffeescript>
- This module shows two ways to read a file line-by-line in node.js.
fs = require 'fs'
- First, let's keep things simple, and do things synchronously. This
- approach is well-suited for simple scripts.
do ->
fn = "read_file.coffee" for line in fs.readFileSync(fn).toString().split '\n' console.log line console.log "DONE SYNC!"
- Now let's complicate things.
- Use the following code when files are large, and memory is
- constrained and/or where you want a large amount of concurrency.
- Protocol:
- Call LineByLineReader, which calls back to you with a reader.
- The reader has two methods.
- next_line: call to this when you want a new line
- close: call this when you are done using the file before
- it has been read completely
- When you call next_line, you must supply two callbacks:
- line_cb: called back when there is a line of text
- done_cb: called back when there is no more text in the file
LineByLineReader = (fn, cb) ->
fs.open fn, 'r', (err, fd) -> bufsize = 256 pos = 0 text = eof = false closed = false reader = next_line: (line_cb, done_cb) -> if eof if text last_line = text text = line_cb last_line else done_cb() return new_line_index = text.indexOf '\n' if new_line_index >= 0 line = text.substr 0, new_line_index text = text.substr new_line_index + 1, text.length - new_line_index - 1 line_cb line else frag = new Buffer(bufsize) fs.read fd, frag, 0, bufsize, pos, (err, bytesRead) -> s = frag.toString('utf8', 0, bytesRead) text += s pos += bytesRead if (bytesRead) reader.next_line line_cb, done_cb else eof = true fs.closeSync(fd) closed = true reader.next_line line_cb, done_cb close: -> # The reader should call this if they abandon mid-file. fs.closeSync(fd) unless closed cb reader
- Test our interface here.
do ->
console.log '---' fn = 'read_file.coffee' LineByLineReader fn, (reader) -> callbacks = process_line: (line) -> console.log line reader.next_line callbacks.process_line, callbacks.all_done all_done: -> console.log "DONE ASYNC!" reader.next_line callbacks.process_line, callbacks.all_done
</lang>
Common Lisp
<lang lisp>(with-open-file (input "file.txt")
(loop for line = (read-line input nil) while line do (format t "~a~%" line)))</lang>
D
<lang d>void main() {
import std.stdio;
foreach (line; "read_a_file_line_by_line.d".File.byLine) line.writeln;
}</lang> The File is managed by reference count, and it gets closed when it gets out of scope or it changes. The 'line' is a char[] (with newline), so if you need a string you have to idup it.
DBL
<lang DBL>;
- Read a file line by line for DBL version 4
RECORD
LINE, A100
PROC
- -----------------------------------------------
OPEN (1,I,"FILE.TXT") [ERR=NOFIL] DO FOREVER BEGIN READS (1,LINE,EOF) [ERR=EREAD] END
EOF, CLOSE 3
GOTO CLOS
- ------------------------------------------------
NOFIL, ;Open error...do something
GOTO CLOS
EREAD, ;Read error...do something
GOTO CLOS
CLOS, STOP</lang>
DCL
<lang DCL>$ open input input.txt $ loop: $ read /end_of_file = done input line $ goto loop $ done: $ close input</lang>
Delphi
<lang Delphi>
procedure ReadFileByLine; var TextFile: text; TextLine: String; begin Assign(TextFile, 'c:\test.txt'); Reset(TextFile); while not Eof(TextFile) do Readln(TextFile, TextLine); CloseFile(TextFile); end;
</lang> The example file (above) "c:\test.txt" is assigned to the text file variable "TextFile" is opened and any line is read in a loop into the string variable "TextLine".
<lang Delphi> procedure ReadFileByLine;
var TextLines : TStringList; i : Integer; begin TextLines := TStringList.Create; TextLines.LoadFromFile('c:\text.txt'); for i := 0 to TextLines.count -1 do ShowMessage(TextLines[i]); end;
</lang>
Above uses the powerful utility classs type TStringList from Classes Unit
See also GNU LGPL (Delphi replacement) Lazarus IDE FreePascal and specifically Lazarus FreePascal Equivalent for TStringList
Draco
<lang draco>\util.g proc nonrec main() void:
/* first we need to declare a file buffer and an input channel */ file() infile; channel input text in_ch; /* a buffer to store the line in is also handy */ [256] char line; word counter; /* to count the lines */ /* open the file, and exit if it fails */ if not open(in_ch, infile, "input.txt") then writeln("cannot open file"); exit(1) fi; counter := 0; /* readln() reads a line and will return false once the end is reached */ /* we pass in a pointer so it stores a C-style zero-terminated string, * rather than try to fill the entire array */ while readln(in_ch; &line[0]) do counter := counter + 1; writeln(counter:5, ": ", &line[0]) od; /* finally, close the file */ close(in_ch)
corp</lang>
Elena
ELENA 4.x : <lang elena>import system'io; import extensions; import extensions'routines;
public program() {
File.assign:"file.txt".forEachLine(printingLn)
}</lang>
Elixir
Two Slightly different solutions in the FileReader namespace <lang Elixir>
defmodule FileReader do # Create a File.Stream and inspect each line def by_line(path) do File.stream!(path) |> Stream.map(&(IO.inspect(&1)))
|> Stream.run
end
def bin_line(path) do # Build the stream in binary instead for performance increase case File.open(path) do # File returns a tuple, {:ok,file}, if successful {:ok, file} ->
IO.binstream(file, :line) |> Stream.map(&(IO.inspect(&1))) |> Stream.run # And returns {:error,reason} if unsuccessful {:error,reason} -> # Use Erlang's format_error to return an error string :file.format_error(reason)
end end end
</lang>
Erlang
read_a_file_line_by_line:into_list/1 is used by Read_a_specific_line_from_a_file. If this task is updated keep backwards compatibility, or change Read_a_specific_line_from_a_file, too. <lang erlang> -module( read_a_file_line_by_line ).
-export( [into_list/1] ).
into_list( File ) ->
{ok, IO} = file:open( File, [read] ), into_list( io:get_line(IO, ), IO, [] ).
into_list( eof, _IO, Acc ) -> lists:reverse( Acc );
into_list( {error, _Error}, _IO, Acc ) -> lists:reverse( Acc );
into_list( Line, IO, Acc ) -> into_list( io:get_line(IO, ), IO, [Line | Acc] ).
</lang>
- Output:
6> read_a_file_line_by_line:into_list("read_a_file_line_by_line.erl"). ["-module( read_a_file_line_by_line ).\n","\n", "-export( [into_list/1] ).\n","\n","into_list( File ) ->\n", "\t{ok, IO} = file:open( File, [read] ),\n", "\tinto_list( io:get_line(IO, ''), IO, [] ).\n","\n","\n", "into_list( eof, _IO, Acc ) -> lists:reverse( Acc );\n", "into_list( {error, _Error}, _IO, Acc ) -> lists:reverse( Acc );\n", "into_list( Line, IO, Acc ) -> into_list( io:get_line(IO, ''), IO, [Line | Acc] ).\n"]
ERRE
<lang ERRE> PROGRAM LETTURA
EXCEPTION
FERROR%=TRUE ! si e' verificata l'eccezione ! PRINT("Il file richiesto non esiste .....")
END EXCEPTION
BEGIN
FERROR%=FALSE PRINT("Nome del file";) INPUT(FILE$) ! chiede il nome del file OPEN("I",1,FILE$) ! apre un file sequenziale in lettura IF NOT FERROR% THEN REPEAT INPUT(LINE,#1,CH$) ! legge una riga .... PRINT(CH$) ! ... la stampa ... UNTIL EOF(1) ! ... fine a fine file END IF PRINT CLOSE(1) ! chiude il file
END PROGRAM </lang> From ERRE manual: use an EXCEPTION to trap a "file not found" error. If you change INPUT(LINE statement with a GET you can read the file one character at time.
Euphoria
<lang euphoria>constant cmd = command_line() constant filename = cmd[2] constant fn = open(filename,"r") integer i i = 1 object x while 1 do
x = gets(fn) if atom(x) then exit end if printf(1,"%2d: %s",{i,x}) i += 1
end while close(fn)</lang>
- Output:
1: constant cmd = command_line() 2: constant filename = cmd[2] 3: constant fn = open(filename,"r") 4: integer i 5: i = 1 6: object x 7: while 1 do 8: x = gets(fn) 9: if atom(x) then 10: exit 11: end if 12: printf(1,"%2d: %s",{i,x}) 13: i += 1 14: end while 15: close(fn)
eui
Create File.txt
Monday Tuesday Wednesday Thursday Tuesday Friday Saturday Wednesday
(1) name the euphoria script file readfile.ex or whatever name you want to give it. Change this line "constant filename = cmd[2]" to "constant filename = cmd[3]" like the following code.
<lang euphoria>constant cmd = command_line() constant filename = cmd[3] constant fn = open(filename,"r") integer i i = 1 object x while 1 do
x = gets(fn) if atom(x) then exit end if printf(1,"%2d: %s",{i,x}) i += 1
end while close(fn)</lang>
From the command line run:
<lang cmd>
eui readfile.ex "File.txt"
</lang>
- Output:
1: Monday 2: Tuesday 3: Wednesday 4: Thursday 5: Tuesday 6: Friday 7: Saturday 8: Wednesday 9:
F#
Using DotNet's System.IO.File.ReadLines iterator: <lang fsharp>open System.IO
[<EntryPoint>] let main argv =
File.ReadLines(argv.[0]) |> Seq.iter (printfn "%s") 0</lang>
Factor
<lang factor> "path/to/file" utf8 [ [ readln dup [ print ] when* ] loop ] with-file-reader</lang>
Fantom
Reads each line from the file "data.txt".
<lang fantom> class Main {
Void main () { File (`data.txt`).eachLine |Str line| { echo ("Line: $line") } }
} </lang>
Forth
<lang forth>4096 constant max-line
- third ( A b c -- A b c A )
>r over r> swap ;
- read-lines ( fileid -- )
begin pad max-line third read-line throw while pad swap ( fileid c-addr u ) \ string excludes the newline 2drop repeat 2drop ;</lang>
Fortran
Old Fortran
Usually, one reads a file with some idea what is in the file and some purpose behind reading it. For this task, suppose that the file just contains plain text, and the text is to be listed, line by line, to the end of the file. The remaining question is how long is the longest record? Some systems enable the reading of a record into a variable that is made big enough to hold whatever the record contains, though perhaps only up to some integer limit such as 65535. Fortran 2000 has formalised the provision of character variables whose size is determined when assigned to (as in TEXT = "This"//"That"
where character variable TEXT is reallocated memory so as to hold eight characters, as needed for the assignment) but without a F2000 compiler to test, it is not clear that this arrangement will work for READ statements as well.
So one is faced again with the question "How long is a piece of string?" when choosing a predefined size. I have confronted a singularly witless format for supplying electricity data that would write up to an entire year's worth of half-hourly values to one line though it might be used to write just a few day's worth of data also. The header line specified the date and time slot for each column as Country,Island,Node,MEAN Energy,01AUG2010 Daily ENERGY,01AUG2010 01,01AUG2010 02,01AUG2010 03, etc.
so all-in-all it was less trouble to specify CHARACTER*246810 for the input record scratchpad so as not to have to struggle with piecemeal input. In this example, change the value of ENUFF.
A common extension after F77 was the "Q" format, which returns the number of characters yet to be read in the input record. In its absence, one would have to just read the input with A format, and if the input record was shorter than ENUFF, then trailing spaces would be appended to ALINE and if ALINE was capacious then this would waste time. Similarly, for output, trailing spaces should be trimmed off, which means that if the input record contained trailing spaces, they would be lost. The scheme here, available via F90 is to use the Q format feature to determine how long the record is, then, request only that many characters to be placed in ALINE, and, write that many characters to the output which will thereby include any supplied trailing spaces. However, there must of course be no attempt to cram any more than ENUFF characters into ALINE, thus the MIN(L,ENUFF) in the READ statement, where the calculation is done on-the-fly. As well, should L be greater than ENUFF this is worth some remark, and in a way that cannot be confused with a listing line, each of which is prefixed by the record number. The default integer size is 32 bit so the numbers could be large but to avoid annoying blank space in the message, I0 format is used. Earlier Fortrans do not allow this, so one might specify I9.
On the other hand, the output device might be less than accommodating when presented with a line longer than it can print: lineprinters typically printed 120, 132 or maybe 144 characters to a line with anything beyond that ignored if it were not a cause for immediate termination. Thus, the WRITE statement could be augmented with ERR = label, END = label
in hope of recovery attempts. If output were to a disc file, the END might be activated on running out of disc space but with windows the system would probably have crashed already. Given a long line to print a teletype printer would just hammer away at the last printing position, but more refined printers would start new lines as needed. I have used a dot-matrix printer that with lineprinter paper could be set to print some 360 cramped characters to a line, and have seen photographs of a special accountant's typewriter with a platen about four feet long. Then for spreadsheet users, there arrived a special printing prog, SIDEWAYS.
Peripheral to the task of reading a file line-by-line is the blather about specifying the file name and opening it. The OPEN statement allows for jumping to an ERR label (just as the READ statement has a jump for end-of-file), and carrying an IOSTAT value to specify the nature of the problem (invalid file name form, file access denied, etc.) but this is all very messy and the error codes are not the same across different systems either. I wish these statements were more like functions and returned TRUE/FALSE or a result code that could be tested in an IF-statement directly, as for example in Burroughs Algol where one could write something like While Read(in) Stuff Do ... ;
- though a READ statement returned true for an I/O error, and false for success, so one defined Ican to be not and wrote While Ican Read(in) Stuff Do ... ;
In the absence of such error reception, ugly messages are presented as the prog. is cancelled, and the most common such error is to name a missing file. So, an INQUIRE statement to check first. This too should have an ERR and IOSTAT blather (the file name might be malformed) but enough is enough. The assignment direction for such codes as EXIST and IOSTAT is left to right rather than the usual right to left (as in FILE = FNAME), but rather than remember this, it is easiest to take advantage of Fortran's (complete) absence of reserved words and define a logical variable EXIST so that the statement is EXIST = EXIST, and the compiler and the programmer can go their own ways. <lang Fortran>
INTEGER ENUFF !A value has to be specified beforehand,. PARAMETER (ENUFF = 2468) !Provide some provenance. CHARACTER*(ENUFF) ALINE !A perfect size? CHARACTER*66 FNAME !What about file name sizes? INTEGER LINPR,IN !I/O unit numbers. INTEGER L,N !A length, and a record counter. LOGICAL EXIST !This can't be asked for in an "OPEN" statement. LINPR = 6 !Standard output via this unit number. IN = 10 !Some unit number for the input file. FNAME = "Read.for" !Choose a file name. INQUIRE (FILE = FNAME, EXIST = EXIST) !A basic question. IF (.NOT.EXIST) THEN !Absent? WRITE (LINPR,1) FNAME !Alas, name the absentee. 1 FORMAT ("No sign of file ",A) !The name might be mistyped. STOP "No file, no go." !Give up. END IF !So much for the most obvious mishap. OPEN (IN,FILE = FNAME, STATUS = "OLD", ACTION = "READ") !For formatted input.
N = 0 !No records read so far. 10 READ (IN,11,END = 20) L,ALINE(1:MIN(L,ENUFF)) !Read only the L characters in the record, up to ENUFF. 11 FORMAT (Q,A) !Q = "how many characters yet to be read", A = characters with no limit. N = N + 1 !A record has been read. IF (L.GT.ENUFF) WRITE (LINPR,12) N,L,ENUFF !Was it longer than ALINE could accommodate? 12 FORMAT ("Record ",I0," has length ",I0,": my limit is ",I0) !Yes. Explain. WRITE (LINPR,13) N,ALINE(1:MIN(L,ENUFF)) !Print the record, prefixed by the count. 13 FORMAT (I9,":",A) !Fixed number size for alignment. GO TO 10 !Do it again.
20 CLOSE (IN) !All done. END !That's all.
</lang>
With F90 and later it is possible to use an ALLOCATE statement to prepare a variable of a size determined at run time, so that one could for each record use the Q
format code (or a new feature of the READ statement) to ascertain the size of the record about to be read, free the storage for the old ALINE and allocate a new sized ALINE, then read that record into ALINE. This avoids worrying about the record overflowing (or underflowing) ALINE, at the cost of hammering at the memory allocation process.
An alternative approach would be to read the file as UNFORMATTED, just reading binary into some convenient scratchpad and then write the content to the output device, which would make what it could of the ASCII world's dithering between CR, CRLF, LFCR and CR as end-of-record markers. However, this would not be reading the file line-by-line.
FreeBASIC
<lang freebasic>' FB 1.05.0 Win64
Open "input.txt" For Input As #1 Dim line_ As String While Not Eof(1)
Line Input #1, line_ read each line Print line_ echo it to the console
Wend Close #1 Print Print "Press any key to quit" Sleep </lang>
Frink
The lines
function can also take an optional second string argument indicating the encoding of the file, and can read from any supported URL type (HTTP, FTP, etc.) or a java.io.InputStream
.
<lang frink>
for line = lines["file:yourfile.txt"]
println[line]
</lang>
Gambas
<lang gambas>Public Sub Main() Dim hFile As File Dim sLine As String
hFile = Open "../InputText.txt" For Input
While Not Eof(hFile)
Line Input #hFile, sLine Print sLine
Wend
End</lang>
GAP
<lang gap>ReadByLines := function(name) local file, line, count; file := InputTextFile(name); count := 0; while true do line := ReadLine(file); if line = fail then break; fi; count := count + 1; od; CloseStream(file); return count; end;
- With amnesty.txt
ReadByLines("amnesty.txt");
- 384</lang>
Genie
<lang genie>[indent=4] /*
Read file line by line, in Genie
valac readFileLines.gs ./readFileLines [filename]
- /
init
fileName:string fileName = (args[1] is null) ? "readFileLines.gs" : args[1] var file = FileStream.open(fileName, "r") if file is null stdout.printf("Error: %s did not open\n", fileName) return
lines:int = 0 line:string? = file.read_line() while line is not null lines++ stdout.printf("%04d %s\n", lines, line) line = file.read_line()</lang>
- Output:
prompt$ valac readFileLines.gs prompt$ ./readFileLines nofile Error: nofile did not open prompt$ ./readFileLines hello.gs 0001 [indent=4] 0002 0003 init 0004 print "Hello, Genie"
Go
- bufio.Scanner
The bufio package provides Scanner, a convenient interface for reading data such as a file of newline-delimited lines of text. Successive calls to the Scan method will step through the 'tokens' of a file, skipping the bytes between the tokens. The specification of a token is defined by a split function of type SplitFunc; the default split function breaks the input into lines with line termination stripped. Split functions are defined in this package for scanning a file into lines, bytes, UTF-8-encoded runes, and space-delimited words. The client may instead provide a custom split function.
Scanning stops unrecoverably at EOF, the first I/O error, or a token too large to fit in the buffer. When a scan stops, the reader may have advanced arbitrarily far past the last token. Programs that need more control over error handling or large tokens, or must run sequential scans on a reader, should use bufio.Reader instead.
<lang go>package main
import ( "bufio" "fmt" "log" "os" )
func init() { log.SetFlags(log.Lshortfile) }
func main() { // Open an input file, exit on error. inputFile, err := os.Open("byline.go") if err != nil { log.Fatal("Error opening input file:", err) }
// Closes the file when we leave the scope of the current function, // this makes sure we never forget to close the file if the // function can exit in multiple places. defer inputFile.Close()
scanner := bufio.NewScanner(inputFile)
// scanner.Scan() advances to the next token returning false if an error was encountered for scanner.Scan() { fmt.Println(scanner.Text()) }
// When finished scanning if any error other than io.EOF occured // it will be returned by scanner.Err(). if err := scanner.Err(); err != nil { log.Fatal(scanner.Err()) } } </lang>
- ReadLine
This function allows files to be rapidly scanned for desired data while minimizing memory allocations. It also handles /r/n line endings and allows unreasonably long lines to be handled as error conditions. <lang go>package main
import (
"bufio" "fmt" "io" "log" "os"
)
func main() {
f, err := os.Open("file") // os.OpenFile has more options if you need them if err != nil { // error checking is good practice // error *handling* is good practice. log.Fatal sends the error // message to stderr and exits with a non-zero code. log.Fatal(err) }
// os.File has no special buffering, it makes straight operating system // requests. bufio.Reader does buffering and has several useful methods. bf := bufio.NewReader(f)
// there are a few possible loop termination // conditions, so just start with an infinite loop. for { // reader.ReadLine does a buffered read up to a line terminator, // handles either /n or /r/n, and returns just the line without // the /r or /r/n. line, isPrefix, err := bf.ReadLine()
// loop termination condition 1: EOF. // this is the normal loop termination condition. if err == io.EOF { break }
// loop termination condition 2: some other error. // Errors happen, so check for them and do something with them. if err != nil { log.Fatal(err) }
// loop termination condition 3: line too long to fit in buffer // without multiple reads. Bufio's default buffer size is 4K. // Chances are if you haven't seen a line terminator after 4k // you're either reading the wrong file or the file is corrupt. if isPrefix { log.Fatal("Error: Unexpected long line reading", f.Name()) }
// success. The variable line is now a byte slice based on on // bufio's underlying buffer. This is the minimal churn necessary // to let you look at it, but note! the data may be overwritten or // otherwise invalidated on the next read. Look at it and decide // if you want to keep it. If so, copy it or copy the portions // you want before iterating in this loop. Also note, it is a byte // slice. Often you will want to work on the data as a string, // and the string type conversion (shown here) allocates a copy of // the data. It would be safe to send, store, reference, or otherwise // hold on to this string, then continue iterating in this loop. fmt.Println(string(line)) }
}</lang>
- ReadString
In comparison, ReadString is a little quick and dirty, but is often good enough. <lang go>package main
import (
"bufio" "fmt" "io" "log" "os"
)
func main() {
f, err := os.Open("file") if err != nil { log.Fatal(err) } bf := bufio.NewReader(f) for { switch line, err := bf.ReadString('\n'); err { case nil: // valid line, echo it. note that line contains trailing \n. fmt.Print(line) case io.EOF: if line > "" { // last line of file missing \n, but still valid fmt.Println(line) } return default: log.Fatal(err) } }
}</lang>
Groovy
<lang groovy>new File("Test.txt").eachLine { line, lineNumber ->
println "processing line $lineNumber: $line"
}</lang>
Haskell
Thanks to laziness, there's no difference between reading the file all at once and reading it line by line.
<lang Haskell>main = do
file <- readFile "linebyline.hs" mapM_ putStrLn (lines file)
</lang>
Icon and Unicon
Line oriented I/O is basic. This program reads lines from "input.txt" into the variable line, but does nothing with it.
<lang Icon>procedure main() f := open("input.txt","r") | stop("cannot open file ",fn) while line := read(f) close(f) end</lang>
J
J currently discourages this "read just one line" approach. In addition to the arbitrary character of lines, there are issues of problem size and scope (what happens when you have a billion characters between your newline delimiters?). Usually, it's easier to just read the entire file, or memory map the file, and when files are so large that that is not practical it's probably better to put the programmer in explicit control of issues like block sizes and exception handling.
This implementation looks for lines separated by ascii character 10. Lines returned here do not include the line separator character. Files with no line-separating character at the end are treated as well formed -- if the last character of the file is the line separator that means that you have an empty line at the end of the file.
This implementation does nothing special when dealing with multi-gigabyte lines. If you encounter an excessively large line and if do not have enough physical memory, your system will experience heavy memory pressure. If you also do not have enough virtual memory to hold a line you will get an out of memory exception.
<lang j>cocurrent 'linereader'
NB. configuration parameter blocksize=: 400000
NB. implementation offset=: 0 position=: 0 buffer=: lines=:
create=: monad define name=: boxxopen y size=: 1!:4 name blocks=: 2 <@(-~/\)\ ~. size <. blocksize * i. 1 + >. size % blocksize )
readblocks=: monad define if. 0=#blocks do. return. end. if. 1<#lines do. return. end. whilst. -.LF e.chars do. buffer=: buffer,chars=. 1!:11 name,{.blocks blocks=: }.blocks lines=: <;._2 buffer,LF end. buffer=: _1{::lines )
next=: monad define if. (#blocks)*.2>#lines do. readblocks end. r=. 0{::lines lines=: }.lines r )</lang>
<lang j> example=: '/tmp/example.txt' conew 'linereader'
next__example
this is line 1
next__example
and this is line 2</lang>
Java
<lang java>import java.io.BufferedReader; import java.io.FileReader;
/**
* Reads a file line by line, processing each line. * * @author $Author$ * @version $Revision$ */
public class ReadFileByLines {
private static void processLine(int lineNo, String line) { // ... }
public static void main(String[] args) { for (String filename : args) { BufferedReader br = null; FileReader fr = null; try { fr = new FileReader(filename); br = new BufferedReader(fr); String line; int lineNo = 0; while ((line = br.readLine()) != null) { processLine(++lineNo, line); } } catch (Exception x) { x.printStackTrace(); } finally { if (fr != null) { try {br.close();} catch (Exception ignoreMe) {} try {fr.close();} catch (Exception ignoreMe) {} } } } }
}</lang>
In Java 7, the try with resources block handles multiple readers and writers without nested try blocks. The loop in the main method would look like this: <lang java5>for (String filename : args) {
try (FileReader fr = new FileReader(filename);BufferedReader br = new BufferedReader(fr)){ String line; int lineNo = 0; while ((line = br.readLine()) != null) { processLine(++lineNo, line); } } catch (Exception x) { x.printStackTrace(); }
}</lang>
fr
and br
are automatically closed when the program exits the try block (it also checks for nulls before closing and throws closing exceptions out of the block).
A more under-the-hood method in Java 7 would be to use the Files
class (line numbers can be inferred from indices in the returned List
):
<lang java5>import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.charset.Charset;
import java.io.IOException;
//...other class code
List<String> lines = null;
try{
lines = Files.readAllLines(Paths.get(filename), Charset.defaultCharset());
}catch(IOException | SecurityException e){
//problem with the file
}</lang>
JavaScript
<lang javascript>var fs = require("fs");
var readFile = function(path) {
return fs.readFileSync(path).toString();
};
console.log(readFile('file.txt'));</lang>
jq
When invoked with the -R option, jq will read each line as a JSON string. For example: <lang sh>$ seq 0 5 | jq -R 'tonumber|sin' 0 0.8414709848078965 0.9092974268256817 0.1411200080598672 -0.7568024953079282 -0.9589242746631385</lang>
To perform any kind of reduction operation while reading the lines one-by-one, one would normally use `input` or `inputs`. For example, to compute the maximum of the above sin values:
<lang sh>$ seq 0 5 | jq -Rn '[inputs | tonumber |sin] | max' 0.9092974268256817</lang>
Jsish
<lang javascript>/* Read by line, in Jsish */ var f = new Channel('read-by-line.jsi'); var line;
while (line = f.gets()) puts(line); f.close();</lang>
- Output:
prompt$ jsish read-by-line.jsi /* Read by line, in Jsish */ var f = new Channel('read-by-line.jsi'); var line; while (line = f.gets()) puts(line); f.close();
Julia
<lang julia>open("input_file","r") do f
for line in eachline(f) println("read line: ", line) end
end</lang>
Kotlin
<lang scala>// version 1.1.2
import java.io.File
fun main(args: Array<String>) {
File("input.txt").forEachLine { println(it) }
}</lang>
Lasso
<lang Lasso>local(f) = file('foo.txt') handle => {#f->close}
- f->forEachLine => {^
#1 '
' // note this simply inserts an HTML line break between each line.
^}</lang>
Liberty BASIC
<lang lb>filedialog "Open","*.txt",file$ if file$="" then end open file$ for input as #f while not(eof(#f))
line input #f, t$ print t$
wend close #f</lang> Mac <lang lb>filedialog "Open","*.txt",file$ if file$="" then end open file$ for input as #f while not(eof(#f))
t$ = inputto$(#f, chr$(13)) print t$
wend close #f </lang> Unix <lang lb>filedialog "Open","*.txt",file$ if file$="" then end open file$ for input as #f while not(eof(#f))
t$ = inputto$(#f, chr$(10)) print t$
wend close #f </lang>
Lingo
The following code works fine for text files using 'CRLF' or 'CR only' as line end characters, but unfortunately not for the *nix default 'LF only' (note: Lingo's implementation Director does not run on Linux. It was originally created for ancient Mac OS systems, and later also ported to Windows): <lang lingo>fp = xtra("fileIO").new() fp.openFile(_movie.path & "input.txt", 1) fileSize = fp.getLength() repeat while TRUE
str = fp.readLine() if str.char[1] = numtochar(10) then delete char 1 of str if the last char of str = numtochar(13) then delete the last char of str put str if fp.getPosition()>=fileSize then exit repeat
end repeat fp.closeFile()</lang>
LiveCode
<lang LiveCode>command readFileLineByLine
local tFile, tLines, startRead put "/usr/share/dict/words" into tFile open file tFile for text read put true into startRead repeat until it is empty and startRead is false put false into startRead read from file tFile for 1 line add 1 to tLines end repeat close file tFile put tLines
end readFileLineByLine</lang>
Logo
There are several words which will return a line of input.
- readline - returns a line as a list of words
- readword - returns a line as a single word, or an empty list if it reached the end of file
- readrawline - returns a line as a single word, with no characters escaped
<lang logo>while [not eof?] [print readline]</lang>
Lua
<lang lua>filename = "input.txt" fp = io.open( filename, "r" )
for line in fp:lines() do
print( line )
end
fp:close() </lang>
Simpler version
The following achieves the same result as the example above, including implicitly closing the file at the end of the loop. <lang Lua> for line in io.lines("input.txt") do
print(line)
end </lang>
M2000 Interpreter
Utf-16LE (wide) and Ansi (locale selective) for Open statement. Documents have Load.Doc statement to load text file. Here we see how we make indexes, and then reopen for input, and move to index, and then load a line.
<lang M2000 Interpreter> Module checkit {
\\ prepare a file document a$ a$={First Line Second line Third Line } Save.Doc a$, "checkthis.txt", 0 ' 0 for UTF-16LE Flush Open "checkthis.txt" For Wide Input as #F While not Eof(#f) { Data Seek(#f) Line Input #F, b$ Print b$ } Close #f Dim Index() \\ copy stack to index(), flush stack Index()=Array([]) \\ change base to base 1 Dim Base 1, Index(len(index())) Open "checkthis.txt" For Wide Input as #F Seek#F, Index(2) Line Input #F, b$ Print b$ ' print second line Close #f \\ prepare Ansi file Print "Ansi File" Save.Doc a$, "checkthis.txt", 1033 ' we use specific locale Flush \\ flush the stack to get indexes oldlocale=locale locale 1033 \\ no Wide clause Open "checkthis.txt" For Input as #F While not Eof(#f) { Data Seek(#f) Line Input #F, b$ Print b$ } Close #f Dim Index() \\ copy stack to index(), flush stack Index()=Array([]) \\ change base to base 1 Dim Base 1, Index(len(index())) Open "checkthis.txt" For Input as #F Seek#F, Index(2) Line Input #F, b$ Print b$ ' print second line Close #f locale oldlocale
} checkit </lang>
Maple
<lang Maple>path := "file.txt": while (true) do input := readline(path): if input = 0 then break; end if: #The line is stored in input end do:</lang>
Mathematica/Wolfram Language
<lang Mathematica>strm=OpenRead["input.txt"]; If[strm=!=$Failed,
While[line=!=EndOfFile, line=Read[strm]; (*Do something*) ]];
Close[strm];</lang>
MATLAB / Octave
The function fgetl() read lines from file:
<lang Matlab>
fid = fopen('foobar.txt','r'); if (fid < 0)
printf('Error:could not open file\n')
else
while ~feof(fid), line = fgetl(fid);
%% process line %%
end;
fclose(fid) end; </lang>
Maxima
<lang maxima>/* Read a file and return a list of all lines */
readfile(name) := block(
[v: [ ], f: openr(name), line], while stringp(line: readline(f)) do v: endcons(line, v), close(f), v
)$</lang>
Mercury
Basic version. <lang mercury>:- module read_a_file_line_by_line.
- - interface.
- - import_module io.
- - pred main(io::di, io::uo) is det.
- - implementation.
- - import_module int, list, require, string.
main(!IO) :-
io.open_input("test.txt", OpenResult, !IO), ( OpenResult = ok(File), read_file_line_by_line(File, 0, !IO) ; OpenResult = error(Error), error(io.error_message(Error)) ).
- - pred read_file_line_by_line(io.text_input_stream::in, int::in,
io::di, io::uo) is det.
read_file_line_by_line(File, !.LineCount, !IO) :-
% We could also use io.read_line/3 which returns a list of characters % instead of a string. io.read_line_as_string(File, ReadLineResult, !IO), ( ReadLineResult = ok(Line), !:LineCount = !.LineCount + 1, io.format("%d: %s", [i(!.LineCount), s(Line)], !IO), read_file_line_by_line(File, !.LineCount, !IO) ; ReadLineResult = eof ; ReadLineResult = error(Error), error(io.error_message(Error)) ).</lang>
Version using a stream fold.
<lang mercury>:- module read_a_file_line_by_line.
- - interface.
- - import_module io.
- - pred main(io::di, io::uo) is det.
- - implementation.
- - import_module int, list, require, string, stream.
main(!IO) :-
io.open_input("test.txt", OpenResult, !IO), ( OpenResult = ok(File), stream.input_stream_fold2_state(File, process_line, 0, Result, !IO), ( Result = ok(_) ; Result = error(_, Error), error(io.error_message(Error)) ) ; OpenResult = error(Error), error(io.error_message(Error)) ).
- - pred process_line(line::in, int::in, int::out, io::di, io::uo) is det.
process_line(line(Line), !LineCount, !IO) :-
!:LineCount = !.LineCount + 1, io.format("%d: %s", [i(!.LineCount), s(Line)], !IO).</lang>
Neko
Need to define a growing buffer to handle streaming unknown sizes, 2 to the 29 max, for this one.
<lang ActionScript>/**
Read a file line by line, in Neko
<doc>
Tectonics: nekoc readfile.neko neko readfile [filename]
</doc>
- /
var stdin = $loader.loadprim("std@file_stdin", 0)()
var file_open = $loader.loadprim("std@file_open", 2)
var file_read_char = $loader.loadprim("std@file_read_char", 1)
/* Read a line from file f into string s returning length without any newline */ var NEKO_MAX = 1 << 29 var strsize = 256 var NEWLINE = 10 var readline = function(f) {
var s = $smake(strsize) var len = 0 var ch var file_exception = false while true { try ch = file_read_char(f) catch problem { file_exception = problem; break; } if ch == NEWLINE break; if $sset(s, len, ch) == null break; else len += 1
if len == strsize - 1 { strsize *= 2 if strsize > NEKO_MAX $throw("Out of string space for readline") var t = s s = $smake(strsize) $sblit(s, 0, t, 0, $ssize(t)) } } if $istrue(file_exception) $rethrow(file_exception) return $ssub(s, 0, len)
}
var infile var cli = $loader.args[0] if cli == null infile = stdin else {
cli = $string(cli) try infile = file_open(cli, "r") catch problem $print(problem, " Can't open ", cli, "\n")
} if infile == null $throw("Can't open " + cli)
var str while true {
try { str = readline(infile) $print(":", str, ":\n") } catch a break;
} </lang>
- Output:
prompt$ nekoc readfile.neko prompt$ seq 1 6 | neko readfile.n :1: :2: :3: :4: :5: :6: prompt$ seq -s',' 1 1000000 | neko readfile | tail -c23 999998,999999,1000000: prompt$ neko readfile.n readfile.neko | tail -4 : str = readline(infile): : $print(":", str, ":\n"): : } catch a break;: :}:
NetRexx
Using Java Scanner
<lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols nobinary
parse arg inFileName .
if inFileName = | inFileName = '.' then inFileName = './data/dwarfs.json' lines = scanFile(inFileName) loop l_ = 1 to lines[0]
say l_.right(4)':' lines[l_] end l_
return
-- Read a file and return contents as a Rexx indexed string method scanFile(inFileName) public static returns Rexx
fileLines = do inFile = File(inFileName) inFileScanner = Scanner(inFile) loop l_ = 1 while inFileScanner.hasNext() fileLines[0] = l_ fileLines[l_] = inFileScanner.nextLine() end l_ inFileScanner.close()
catch ex = FileNotFoundException ex.printStackTrace end
return fileLines
</lang>
Using Java Reader
<lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols nobinary
parse arg inFileName .
if inFileName = | inFileName = '.' then inFileName = './data/dwarfs.json' lines = readFile(inFileName) loop l_ = 1 to lines[0]
say l_.right(4)':' lines[l_] end l_
return
-- Read a file and return contents as a Rexx indexed string method readFile(inFileName) public static returns Rexx
fileLines = inLine = String null inFileBR = BufferedReader null
do inFile = File(inFileName) inFileBR = BufferedReader(FileReader(inFile)) loop l_ = 1 until inline = null inLine = inFileBR.readLine() if inline \= null then do fileLines[0] = l_ fileLines[l_] = inLine end end l_
catch exFNF = FileNotFoundException exFNF.printStackTrace catch exIO = IOException exIO.printStackTrace finally if inFileBR \= null then do do inFileBR.close() catch ex = IOException ex.printStackTrace end end end
return fileLines
</lang>
NewLISP
<lang NewLISP> (set 'in-file (open "filename" "read")) (while (read-line in-file)
(write-line))
(close in-file)</lang>
Nim
<lang nim>for line in lines "input.txt":
echo line</lang>
Objeck
<lang objeck> bundle Default {
class ReadFile { function : Main(args : String[]) ~ Nil { f := IO.FileReader->New("in.txt"); if(f->IsOpen()) { string := f->ReadString(); while(f->IsEOF() = false) { string->PrintLine(); string := f->ReadString(); }; f->Close(); }; } }
} </lang>
Objective-C
To read an entire file into a string, you can: <lang objc>NSString *path = [NSString stringWithString:@"/usr/share/dict/words"]; NSError *error = nil; NSString *words = [[NSString alloc] initWithContentsOfFile:path
encoding:NSUTF8StringEncoding error:&error];
</lang>
Use the UTF-8 encoder on ASCII.
Now to get the individual lines, break down the string:
<lang objc>NSArray* lines = [words componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];</lang>
OCaml
<lang ocaml>let () =
let ic = open_in "input.txt" in try while true do let line = input_line ic in print_endline line done with End_of_file -> close_in ic</lang>
But if we want to write a functional loading function we should remember that the try/with
couple breaks the tail recursion. So we should externalise it outside of the loop in another function:
<lang ocaml>let input_line_opt ic =
try Some (input_line ic) with End_of_file -> None
let read_lines ic =
let rec aux acc = match input_line_opt ic with | Some line -> aux (line::acc) | None -> (List.rev acc) in aux []
let lines_of_file filename =
let ic = open_in filename in let lines = read_lines ic in close_in ic; (lines)</lang>
we use it like this:
<lang ocaml>let () =
let lines = lines_of_file "unixdict.txt" in List.iter print_endline lines</lang>
Oforth
<lang Oforth>: readFile(fileName)
| line | File new(fileName) forEach: line [ line println ] ;</lang>
PARI/GP
GP has an unfortunate limitations that prevents reading files line-by-line, but it's just as well since its file-handling capabilities are poor. The TODO file lists one desiderata as adding a t_FILE
, which if added would presumably have support for this sort of operation.
Thus the usual way of interacting with files in more than the simple way allowed by read
is done by PARI with the usual C commands:
<lang C>FILE *f = fopen(name, "r");
if (!f) {
pari_err(openfiler, "input", name);
}
while(fgets(line, MAX_LINELEN, f) != NULL) {
// ...
}</lang>
Pascal
Works for text files. "testin.txt" must exist in directory of program and you must have read/write access. No IO-Checks. <lang pascal>(* Read a text-file line by line *)
program ReadFileByLine; var InputFile,OutputFile: text; TextLine: String; begin Assign(InputFile, 'testin.txt'); Reset(InputFile); Assign(OutputFile, 'testout.txt'); Rewrite(OutputFile); while not Eof(InputFile) do begin ReadLn(InputFile, TextLine); (* do someting with TextLine *) WriteLn(OutputFile, TextLine) end; Close(InputFile); Close(OutputFile) end.</lang>
Perl
For the simple case of iterating over the lines of a file you can do: <lang perl>open(my $fh, '<', 'foobar.txt')
|| die "Could not open file: $!";
while (<$fh>) { # each line is stored in $_, with terminating newline
# chomp, short for chomp($_), removes the terminating newline chomp; process($_);
} close $fh;</lang> File encoding can be specified like: <lang perl>open(my $fh, '< :encoding(UTF-8)', 'foobar.txt')
|| die "Could not open file: $!";</lang>
The angle bracket operator < >
reads a filehandle line by line. (The angle bracket operator can also be used to open and read from files that match a specific pattern, by putting the pattern in the brackets.)
Without specifying the variable that each line should be put into, it automatically puts it into $_
, which is also conveniently the default argument for many Perl functions. If you wanted to use your own variable, you can do something like this:
<lang perl>open(my $fh, '<', 'foobar.txt')
|| die "Could not open file: $!";
while (my $line = <$fh>) {
chomp $line; process($line);
} close $fh;</lang>
The special use of the angle bracket operator with nothing inside, will read from all files whose names were specified on the command line: <lang perl>while (<>) {
chomp; process($_);
}</lang>
As noted in perlop.pod
under "I/O Operators", <>
opens with the 2-arg open()
and so can read from a piped command. This can be convenient but is also very much insecure--a user could supply a file with the name like
<lang Shell>perl myscript.pl 'rm -rf / |'</lang>
or any other arbitrary command, which will be executed when perl attempts to open a pipe for it. As such, this feature is best reserved for one-liners and is bad practice to use in production code. The same is true for the open(FILEHANDLE, EXPR) form of open as opposed to open(FILEHANDLE, MODE, EXPR). (See perlfunc.pod
on the open()
function.)
The ARGV::readonly
module can defang @ARGV
by modifying the names to ensure they are treated only as files by the open()
.
The readline function can be used instead of < >: <lang perl>open(my $fh, '<', 'foobar.txt') or die "$!"; while (readline $fh) { ... }
while (my $line = readline $fh) { ... } close $fh;</lang> The readline function is the internal function used to implement < >, but can be used directly and is useful for conveying programmer intent in certain situations.
Phix
constant fn = open(command_line()[2],"r") integer lno = 1 object line while 1 do line = gets(fn) if atom(line) then exit end if printf(1,"%2d: %s",{lno,line}) lno += 1 end while close(fn) {} = wait_key()
- Output:
1: constant fn = open(command_line()[2],"r") 2: integer lno = 1 3: object line 4: while 1 do 5: line = gets(fn) 6: if atom(line) then exit end if 7: printf(1,"%2d: %s",{lno,line}) 8: lno += 1 9: end while 10: close(fn) 11: {} = wait_key()
Phixmonti
<lang Phixmonti>include ..\Utilitys.pmt
argument 1 get "r" fopen var f
true while
f fgets number? if drop f fclose false else print true endif
endwhile</lang>
PHP
<lang php><?php $file = fopen(__FILE__, 'r'); // read current file while ($line = fgets($file)) {
$line = rtrim($line); // removes linebreaks and spaces at end echo strrev($line) . "\n"; // reverse line and upload it
}</lang>
<lang php><?php // HOW TO ECHO FILE LINE BY LINE FROM THE COMMAND LINE: php5-cli $file = fopen('test.txt', 'r'); // OPEN FILE WITH READ ACCESS while (!feof($file)) {
$line = rtrim(fgets($file)); // REMOVE TRAILING WHITESPACE AND GET LINE if($line != NULL) echo("$line\n"); // IF THE LINE ISN'T NULL, ECHO THE LINE
}</lang>
Picat
read_line/1
The proper way of reading a file line by line is to use read_line(FH)
. This is he recommended way for a very large files.
<lang Picat>go =>
FD = open("unixdict.txt"), while (not at_end_of_stream(FD)) Line = read_line(FD), println(Line) end, close(FD), nl.</lang>
read_file_lines
For reasonable sized files, read_file_lines/1
is usually the way to go.
<lang Picat>go2 =>
foreach(Line in read_file_lines("unixdict.txt")) println(Line) end.</lang>
PicoLisp
<lang PicoLisp>(in "foobar.txt"
(while (line) (process @) ) )</lang>
PL/I
<lang pli> read: procedure options (main);
declare line character (500) varying;
on endfile (sysin) stop;
do forever; get edit (line)(L); end;
end read; </lang>
PowerShell
<lang PowerShell>$reader = [System.IO.File]::OpenText($mancorfile) try { do { $line = $reader.ReadLine() if ($line -eq $null) { break } DoSomethingWithLine($line) } while ($TRUE) } finally { $reader.Close() } </lang>
PureBasic
<lang PureBasic>FileName$ = OpenFileRequester("","foo.txt","*.txt",0)
If ReadFile(0, FileName$) ; use ReadFile instead of OpenFile to include read-only files
BOMformat = ReadStringFormat(0) ; reads the BOMformat (Unicode, UTF-8, ASCII, ...) While Not Eof(0) line$ = ReadString(0, BOMformat) DoSomethingWithTheLine(Line) Wend CloseFile(0)
EndIf</lang>
Python
For the simple case of iterating over the lines of a file you can do: <lang python>with open("foobar.txt") as f:
for line in f: process(line)</lang>
The with statement ensures the correct closing of the file after it is processed, and iterating over the file object f
, adjusts what is considered line separator character(s) so the code will work on multiple operating systems such as Windows, Mac, and Solaris without change.
Any exceptional conditions seen when processing the file will raise an exception. Leaving the while loop because of an exception will also cause the file to be correctly closed on the way.
Python also has the fileinput module. This can process multiple files parsed from the command line and can be set to modify files 'in-place'. <lang python>import fileinput for line in fileinput.input():
process(line)
</lang>
R
<lang R>conn <- file("notes.txt", "r") while(length(line <- readLines(conn, 1)) > 0) {
cat(line, "\n")
}</lang>
Racket
<lang racket>(define (read-next-line-iter file) (let ((line (read-line file 'any))) (unless (eof-object? line) (display line) (newline) (read-next-line-iter file)))) (call-with-input-file "foobar.txt" read-next-line-iter)</lang>
<lang racket>(define in (open-input-file file-name)) (for ([line (in-lines in)])
(displayln line))
(close-input-port in)</lang>
Raku
(formerly Perl 6) The lines method is lazy so the following code does indeed read the file line by line, and not all at once. <lang perl6>for open('test.txt').lines {
.say
}</lang>
In order to be more explicit about the file being read on line at a time, one can write: <lang perl6>my $f = open 'test.txt'; while my $line = $f.get {
say $line;
}</lang>
RapidQ
<lang vb> $Include "Rapidq.inc" dim file as qfilestream
if file.open("c:\A Test.txt", fmOpenRead) then
while not File.eof print File.readline wend
else
print "Cannot read file"
end if
input "Press enter to exit: ";a$ </lang>
REXX
belt and suspenders
The first linein invocation is used to position the record pointer (current position in the file for reading)
in case the parent (REXX) program has already read (for instance) the first couple of records, and the
beginning of the file needs to be re-established so the reading can start from the beginning of the file.
The lineout BIF closes the file (in most REXX interpreters); this is done for general housekeeping.
<lang rexx>/*REXX program reads and displays (with a count) a file, one line at a time. */
parse arg fID . /*obtain optional argument from the CL.*/
if fID== then exit 8 /*Was no fileID specified? Then quit. */
say center(' displaying file: ' fID" ", 79, '═') /*show the name of the file being read.*/
call linein fID, 1, 0 /*see the comment in the section header*/
say /* [↓] show a file's contents (lines).*/
do #=1 while lines(fID)\==0 /*loop whilst there are lines in file. */ y= linein(fID) /*read a line and assign contents to Y.*/ say y /*show the content of the line (record)*/ end /*#*/
say /*stick a fork in it, we're all done. */
say center(' file ' fID " has " #-1 ' records.', 79, '═') /*show rec count. */
call lineout fID /*close the input file (most REXXes). */</lang>
deluxe version
This REXX version, in addition to the first version (above), has the ability to show the record number and length as the
file's contents are being displayed.
It also has the ability to only show a specific line (or a group of lines).
It can also just show the last line.
If appropriate, the program will show the total number of lines in the file.
<lang rexx></lang>
- output when using the input of: 123456.TXT
════════════════════════ displaying file: 123456.TXT ═════════════════════════ 11 22222222 33333333 444 5555555555 6666666 111 2222222222 3333333333 4444 5555555555 666666666 1111 22 22 33 33 44 44 55 66 66 11 22 22 33 44 44 55 66 11 22 33 44 44 55 66 11 22 333 4444444444 5555555 66 666666 11 22 333 4444444444 55555555 6666666666 11 22 33 44 55 666 66 11 22 33 44 55 66 66 11 22 22 33 33 44 55 55 66 66 111111 2222222222 3333333333 4444 5555555555 66666666 111111 2222222222 33333333 4444 55555555 666666 ─────────────────────────────────────────── file 123456.TXT has 12 records.
- output when using the input of: 123456.TXT -1
════════════════════════ displaying file: 123456.TXT ═════════════════════════ ─────────────────────────────────────────────────────── record#= 1 length= 80 11 22222222 33333333 444 5555555555 6666666 ─────────────────────────────────────────────────────── record#= 2 length= 81 111 2222222222 3333333333 4444 5555555555 666666666 ─────────────────────────────────────────────────────── record#= 3 length= 81 1111 22 22 33 33 44 44 55 66 66 ─────────────────────────────────────────────────────── record#= 4 length= 73 11 22 22 33 44 44 55 66 ─────────────────────────────────────────────────────── record#= 5 length= 73 11 22 33 44 44 55 66 ─────────────────────────────────────────────────────── record#= 6 length= 80 11 22 333 4444444444 5555555 66 666666 ─────────────────────────────────────────────────────── record#= 7 length= 81 11 22 333 4444444444 55555555 6666666666 ─────────────────────────────────────────────────────── record#= 8 length= 81 11 22 33 44 55 666 66 ─────────────────────────────────────────────────────── record#= 9 length= 81 11 22 33 44 55 66 66 ────────────────────────────────────────────────────── record#= 10 length= 81 11 22 22 33 33 44 55 55 66 66 ────────────────────────────────────────────────────── record#= 11 length= 80 111111 2222222222 3333333333 4444 5555555555 66666666 ────────────────────────────────────────────────────── record#= 12 length= 79 111111 2222222222 33333333 4444 55555555 666666 ─────────────────────────────────────────── file 123456.TXT has 12 records.
- output when using the input of: 123456.TXT 5 6
═════════════════════════ displaying file: 1234.txt ══════════════════════════ 11 22 33 44 44 11 22 333 4444444444
- output when using the input of: 123456.TXT 5 6
════════════════════════ displaying file: 123456.TXT ═════════════════════════
───────────────────────────────────────── record#= 12 (last line) length= 79
111111 2222222222 33333333 4444 55555555 666666
─────────────────────────────────────────── file 123456.TXT has 12 records.
ARexx version
<lang rexx>/* Also works with Regina if you state OPTIONS AREXX_BIFS ; OPTIONS AREXX_SEMANTICS */ filename='file.txt' contents= IF Open(filehandle,filename,'READ') THEN DO UNTIL EOF(filehandle)
line=ReadLn(filehandle) SAY line contents=contents || line || '0a'x END
ELSE EXIT 20 CALL Close filehandle EXIT 0</lang>
Ring
<lang ring> fp = fopen("C:\Ring\ReadMe.txt","r") r = "" while isstring(r)
r = fgetc(fp) if r = char(10) see nl else see r ok
end fclose(fp) </lang>
Ruby
<lang ruby>IO.foreach "foobar.txt" do |line|
# Do something with line. puts line
end</lang>
<lang ruby># File inherits from IO, so File.foreach also works. File.foreach("foobar.txt") {|line| puts line}</lang>
<lang ruby># IO.foreach and File.foreach can also read a subprocess. IO.foreach "| grep afs3 /etc/services" do |line|
puts line
end</lang>
Caution! IO.foreach and File.foreach take a portname. To open an arbitrary filename (which might start with "|"), you must use File.open, then IO#each (or IO#each_line). The block form of File.open automatically closes the file after running the block.
<lang ruby>filename = "|strange-name.txt" File.open(filename) do |file|
file.each {|line| puts line}
end</lang>
Run BASIC
<lang runbasic>open DefaultDir$ + "\public\filetest.txt" for input as #f while not(eof(#f))
line input #f, a$ print a$
wend close #f </lang>
Rust
<lang rust>use std::io::{BufReader,BufRead}; use std::fs::File;
fn main() {
let file = File::open("file.txt").unwrap(); for line in BufReader::new(file).lines() { println!("{}", line.unwrap()); }
}</lang>
- Output:
First line of the file! Second line of the file!
Scala
<lang scala>import scala.io._ Source.fromFile("foobar.txt").getLines.foreach(println)</lang>
Scheme
<lang scheme>; Commented line below should be uncommented to use read-line with Guile
- (use-modules (ice-9 rdelim))
(define file (open-input-file "input.txt")) (do ((line (read-line file) (read-line file))) ((eof-object? line))
(display line) (newline))</lang>
Sed
Through a .sed file: <lang sed>#!/bin/sed -f p </lang>
or through a one-liner in bash: <lang bash> sed p filename </lang>
Seed7
<lang seed7>$ include "seed7_05.s7i";
const proc: main is func
local var file: aFile is STD_NULL; var string: line is ""; begin aFile := open("input.txt", "r"); while hasNext(aFile) do readln(aFile, line); writeln("LINE: " <& line); end while; end func;</lang>
The function hasNext returns TRUE when at least one character can be read successfully.
SenseTalk
The simple way: <lang sensetalk>repeat with each line of file "input.txt" put it end repeat </lang>
The more traditional way: <lang sensetalk>put "input.txt" into myFile open file myFile
repeat forever read from file myFile until return if it is empty then exit repeat put it end repeat
close file myFile</lang>
Sidef
FileHandle.each{} is lazy, allowing us to do this: <lang ruby>File(__FILE__).open_r.each { |line|
print line
}</lang>
Same thing explicitly: <lang ruby>var fh = File(__FILE__).open_r while (fh.readline(\var line)) {
print line
}</lang>
Smalltalk
<lang smalltalk> (StandardFileStream oldFileNamed: 'test.txt') contents lines do: [ :each | Transcript show: each. ] </lang>
<lang smalltalk>'foobar.txt' asFilename readingLinesDo:[:eachLine | eachLine printCR]</lang> alternatively: <lang smalltalk>|s| s := 'foobar.txt' asFilename readStream. [ s atEnd ] whileFalse:[
s nextLine printCR.
]. s close</lang> alternatively: <lang smalltalk>'foobar.txt' asFilename contents do:[:eachLine | eachLine printCR].</lang>
SNOBOL4
In SNOBOL4, file I/O is done by associating a file with a variable. Every subsequent access to the variable provides the next record of the file. Options to the input() function allow the file to be opened in line mode, fixed-blocksize (raw binary) mode, and with various sharing options. The input() operation generally fails (in most modern implementations) if the file requested is not found (in earlier implementations, that failure is reported the same way as end-of-file when the first actual read from the file is attempted). You can specify the file unit number to use (a vestigial remnant of the Fortran I/O package used by original Bell Labs SNOBOL4 implementations... in this case, I'll use file unit 20). Accessing the variable fails (does not succeed) when the end of file is reached.
<lang snobol4> input(.infile,20,"readfrom.txt") :f(end) rdloop output = infile :s(rdloop) end</lang>
Sparkling
<lang sparkling>let f = fopen("foo.txt", "r"); if f != nil {
var line; while (line = fgetline(f)) != nil { print(line); }
fclose(f);
}</lang>
SPL
<lang spl>f = "file.txt" > !#.eof(f)
#.output(#.readline(f))
<</lang>
Tcl
<lang tcl>set f [open "foobar.txt"] while {[gets $f line] >= 0} {
# This loops over every line puts ">>$line<<"
} close $f</lang>
TorqueScript
Read a file line by line:
<lang TorqueScript> //Create a file object
%f = new fileObject();
//Open and read a file
%f.openForRead("PATH/PATH.txt");
while(!%f.isEOF()) { //Read each line from our file
%line = %f.readLine(); }
//Close the file object
%f.close();
//Delete the file object
%f.delete(); </lang>
Turing
For a named file: <lang turing>var f : int open : f, "rosetta.txt", get loop
exit when eof (f) var line: string get : f, line:* put line
end loop close : f</lang>
For a command line argument file (e.g. program.x rosetta.txt): <lang turing>loop
exit when eof (1) var line: string get : 1, line:* put line
end loop</lang>
For standard input (e.g., program.x < rosetta.txt): <lang turing>loop
exit when eof var line : string get line:* put line
end loop</lang>
TUSCRIPT
<lang tuscript> $$ MODE TUSCRIPT
datei="rosetta.txt" ERROR/STOP OPEN (datei,READ,-std-)
ACCESS q: READ/RECORDS/UTF8 $datei s,line
LOOP READ/NEXT/EXIT q PRINT line ENDLOOP
ENDACCESS q </lang> or: <lang tuscript> LOOP line=datei
PRINT line
ENDLOOP </lang>
Ultimate++
Taken from C++ U++ section
<lang cpp>#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN { FileIn in(CommandLine()[0]); while(in && !in.IsEof()) Cout().PutLine(in.GetLine()); }</lang>
UNIX Shell
Redirect standard input from a file, and then use IFS= read -r line
to read each line.
- mksh(1) manual says, "If
read
is run in a loop such aswhile read foo; do ...; done
then leading whitespace will be removed (IFS) and backslashes processed. You might want to usewhile IFS= read -r foo; do ...; done
for pristine I/O."
<lang bash># This while loop repeats for each line of the file.
- This loop is inside a pipeline; many shells will
- run this loop inside a subshell.
cat input.txt | while IFS= read -r line ; do
printf '%s\n' "$line"
done</lang>
<lang bash># This loop runs in the current shell, and can read both
- the old standard input (fd 1) and input.txt (fd 3).
exec 3<input.txt while IFS= read -r line <&3 ; do
printf '%s\n' "$line"
done exec 3>&-</lang>
<lang bash># The old Bourne Shell interprets 'IFS= read' as 'IFS= ; read'.
- It requires extra code to restore the original value of IFS.
exec 3<input.txt oldifs=$IFS while IFS= ; read -r line <&3 ; do
IFS=$oldifs printf '%s\n' "$line"
done IFS=$oldifs exec 3>&-</lang>
Ursa
Reads the file "filename.txt" and outputs it to the console line by line. <lang ursa>decl file f f.open "filename.txt" while (f.hasline)
out (in string f) endl console
end while</lang>
Vala
Reads and prints out file line by line: <lang vala> public static void main(){ var file = FileStream.open("foo.txt", "r");
string line = file.read_line(); while (line != null){ stdout.printf("%s\n", line); line = file.read_line(); } } </lang>
VBA
<lang vb>' Read a file line by line Sub Main()
Dim fInput As String, fOutput As String 'File names Dim sInput As String, sOutput As String 'Lines fInput = "input.txt" fOutput = "output.txt" Open fInput For Input As #1 Open fOutput For Output As #2 While Not EOF(1) Line Input #1, sInput sOutput = Process(sInput) 'do something Print #2, sOutput Wend Close #1 Close #2
End Sub 'Main</lang>
VBScript
<lang vb> FilePath = "<SPECIFY FILE PATH HERE>" Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = objFSO.OpenTextFile(FilePath,1) Do Until objFile.AtEndOfStream WScript.Echo objFile.ReadLine Loop objFile.Close Set objFSO = Nothing </lang>
Vedit macro language
On Vedit, you do not actually read file line by line. File reading and writing is handled by automatic file buffering while you process the file.
This example reads the source code of this macro, copies it line by line into a new buffer and adds line numbers. <lang vedit>File_Open("line_by_line.vdm")
- 10 = Buf_Num // edit buffer for input file
- 11 = Buf_Free // edit buffer for output
- 1 = 1 // line number
while (!At_EOF) {
Reg_Copy(20,1) // read one line into text register 20 Buf_Switch(#11) // switch to output file Num_Ins(#1++, NOCR) // write line number Ins_Text(" ") Reg_Ins(20) // write the line Buf_Switch(#10) // switch to input file Line(1) // next line
} Buf_Close(NOMSG) // close the input file Buf_Switch(#11) // show the output </lang>
- Output:
1 File_Open("line_by_line.vdm") 2 #10 = Buf_Num // edit buffer for input file 3 #11 = Buf_Free // edit buffer for output 4 #1 = 1 // line number 5 while (!At_EOF) { 6 Reg_Copy(20,1) // read one line into text register 20 7 Buf_Switch(#11) // switch to output file 8 Num_Ins(#1++, NOCR) // write line number 9 Ins_Text(" ") 10 Reg_Ins(20) // write the line 11 Buf_Switch(#10) // switch to input file 12 Line(1) // next line 13 } 14 Buf_Close(NOMSG) // close the input file 15 Buf_Switch(#11) // show the output
Visual Basic
Simple version
<lang vb>' Read a file line by line Sub Main()
Dim fInput As String, fOutput As String 'File names Dim sInput As String, sOutput As String 'Lines Dim nRecord As Long fInput = "input.txt" fOutput = "output.txt" On Error GoTo InputError Open fInput For Input As #1 On Error GoTo 0 'reset error handling Open fOutput For Output As #2 nRecord = 0 While Not EOF(1) Line Input #1, sInput sOutput = Process(sInput) 'do something nRecord = nRecord + 1 Print #2, sOutput Wend Close #1 Close #2 Exit Sub
InputError:
MsgBox "File: " & fInput & " not found"
End Sub 'Main</lang>
Complex version
<lang vb>' Read lines from a file ' ' (c) Copyright 1993 - 2011 Mark Hobley ' ' This code was ported from an application program written in Microsoft Quickbasic ' ' This code can be redistributed or modified under the terms of version 1.2 of ' the GNU Free Documentation Licence as published by the Free Software Foundation.
Sub readlinesfromafile()
var.filename = "foobar.txt" var.filebuffersize = ini.inimaxlinelength Call openfileread If flg.error = "Y" Then flg.abort = "Y" Exit Sub End If If flg.exists <> "Y" Then flg.abort = "Y" Exit Sub End If
readfilelabela:
Call readlinefromfile If flg.error = "Y" Then flg.abort = "Y" Call closestream flg.error = "Y" Exit Sub End If If flg.endoffile <> "Y" Then ' We have a line from the file Print message$ GoTo readfilelabela End If ' End of file reached ' Close the file and exit Call closestream Exit Sub
End Sub
Sub openfileread()
flg.streamopen = "N" Call checkfileexists If flg.error = "Y" Then Exit Sub If flg.exists <> "Y" Then Exit Sub Call getfreestream If flg.error = "Y" Then Exit Sub var.errorsection = "Opening File" var.errordevice = var.filename If ini.errortrap = "Y" Then On Local Error GoTo openfilereaderror End If flg.endoffile = "N" Open var.filename For Input As #var.stream Len = var.filebuffersize flg.streamopen = "Y" Exit Sub
openfilereaderror:
var.errorcode = Err Call errorhandler resume '!!
End Sub
Public Sub checkfileexists()
var.errorsection = "Checking File Exists" var.errordevice = var.filename If ini.errortrap = "Y" Then On Local Error GoTo checkfileexistserror End If flg.exists = "N" If Dir$(var.filename, 0) <> "" Then flg.exists = "Y" End If Exit Sub
checkfileexistserror:
var.errorcode = Err Call errorhandler
End Sub
Public Sub getfreestream()
var.errorsection = "Opening Free Data Stream" var.errordevice = "" If ini.errortrap = "Y" Then On Local Error GoTo getfreestreamerror End If var.stream = FreeFile Exit Sub
getfreestreamerror:
var.errorcode = Err Call errorhandler resume '!!
End Sub
Sub closestream()
If ini.errortrap = "Y" Then On Local Error GoTo closestreamerror End If var.errorsection = "Closing Stream" var.errordevice = "" flg.resumenext = "Y" Close #var.stream If flg.error = "Y" Then flg.error = "N" '!! Call unexpectederror End If flg.streamopen = "N" Exit Sub
closestreamerror:
var.errorcode = Err Call errorhandler resume next
End Sub
Public Sub errorhandler()
tmp$ = btrim$(var.errorsection) tmp2$ = btrim$(var.errordevice) If tmp2$ <> "" Then tmp$ = tmp$ + " (" + tmp2$ + ")" End If tmp$ = tmp$ + " : " + Str$(var.errorcode) tmp1% = MsgBox(tmp$, 0, "Error!") flg.error = "Y" If flg.resumenext = "Y" Then flg.resumenext = "N"
' Resume Next
Else flg.error = "N"
' Resume
End If
End Sub
Public Function btrim$(arg$)
btrim$ = LTrim$(RTrim$(arg$))
End Function</lang>
Visual Basic .NET
<lang vbnet>Imports System.IO
' Loop through the lines of a file. ' Function assumes that the file exists. Private Sub ReadLines(ByVal FileName As String)
Dim oReader As New StreamReader(FileName) Dim sLine As String = Nothing
While Not oReader.EndOfStream sLine = oReader.ReadLine() ' Do something with the line. End While
oReader.Close()
End Sub</lang>
Wart
<lang wart>with infile "x"
drain (read_line)</lang>
Wren
<lang ecmascript>import "io" for File
var lines = [] // store lines read File.open("input.txt") { |file|
var offset = 0 var line = "" while(true) { var b = file.readBytes(1, offset) offset = offset + 1 if (b == "\n") { lines.add(line) line = "" // reset line variable } else if (b == "\r") { // Windows // wait for following "\n" } else if (b == "") { // end of stream return } else { line = line + b } }
}
System.print(lines.join("\n")) // print out lines</lang>
XPL0
File is redirected on command line i.e: <file.txt <lang XPL0>int C; [repeat repeat C:= ChIn(1); \repeat until end-of-line
ChOut(0, C); until C < $20; \CR, LF, or EOF
until C = \EOF\ $1A; \repeat until end-of-file ]</lang>
zkl
So many ways, here are a few <lang zkl>foreach line in (File("foo.zkl")){print(line)}</lang> <lang zkl>File("foo.zkl").pump(Console.print)</lang> <lang zkl>Utils.zipWith(False,fcn(a,b){"%d: %s".fmt(a,b).print()},
[0..],File("foo.zkl","r"))
--> 0: var R; n:=GarbageMan.gcCount; 1: ref := GarbageMan.WeakRef(String("the","quick brown fox")); ...</lang>
- Programming Tasks
- File handling
- Simple
- GUISS/Omit
- Lotus 123 Macro Scripting/Omit
- Openscad/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- Unlambda/Omit
- 360 Assembly
- 8th
- AArch64 Assembly
- Action!
- Ada
- Aime
- ALGOL 68
- APL
- Amazing Hopper
- ARM Assembly
- Astro
- AutoHotkey
- AWK
- BASIC
- BaCon
- IS-BASIC
- Locomotive Basic
- OxygenBasic
- QBasic
- UBasic/4tH
- ZX Spectrum Basic
- BASIC256
- Batch File
- BBC BASIC
- Bracmat
- Brat
- C
- C sharp
- C++
- U++
- Clojure
- CLU
- COBOL
- CoffeeScript
- Common Lisp
- D
- DBL
- DCL
- Delphi
- Draco
- Elena
- Elixir
- Erlang
- ERRE
- Euphoria
- Eui
- F Sharp
- Factor
- Fantom
- Forth
- Fortran
- FreeBASIC
- Frink
- Gambas
- GAP
- Genie
- Go
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Jsish
- Julia
- Kotlin
- Lasso
- Liberty BASIC
- Lingo
- LiveCode
- Logo
- Lua
- M2000 Interpreter
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- Maxima
- Mercury
- Neko
- NetRexx
- NewLISP
- Nim
- Objeck
- Objective-C
- OCaml
- Oforth
- PARI/GP
- Pascal
- Perl
- Phix
- Phix/basics
- Phixmonti
- PHP
- Picat
- PicoLisp
- PL/I
- PowerShell
- PureBasic
- Python
- R
- Racket
- Raku
- RapidQ
- REXX
- Ring
- Ruby
- Run BASIC
- Rust
- Scala
- Scheme
- Sed
- Seed7
- SenseTalk
- Sidef
- Smalltalk
- SNOBOL4
- Sparkling
- SPL
- Tcl
- TorqueScript
- Turing
- TUSCRIPT
- Ultimate++
- UNIX Shell
- Ursa
- Vala
- VBA
- VBScript
- Vedit macro language
- Visual Basic
- Visual Basic .NET
- Wart
- Wren
- XPL0
- Zkl