Using "PRINT #" and "INPUT ()" on binary files
Re: Using "PRINT #" and "INPUT ()" on binary files
Yes, I've also noted, that someone must have been "diddling", with the forum SW.
(just check the massively increased "max. users online on date", was at "201")
(just check the massively increased "max. users online on date", was at "201")
Re: Using "PRINT #" and "INPUT ()" on binary files
Normally Get#/Put# should be used with Open For Binary, and [Line] Input#/Input()/Print# with textual Open For Input/Output.
I already noticed that binary access mode is also compatible with Print#, [Line] Input # and Input() (viewtopic.php?p=218697#p218697).
But this is not currently a requirement (not in the documentation) and therefore we can not guarantee that this will always be true for future versions of fbc.
I already noticed that binary access mode is also compatible with Print#, [Line] Input # and Input() (viewtopic.php?p=218697#p218697).
But this is not currently a requirement (not in the documentation) and therefore we can not guarantee that this will always be true for future versions of fbc.
Re: Using "PRINT #" and "INPUT ()" on binary files
Actually, for PRINT # documantation says:
For INPUT #filenum
The file number of a file or device opened for Output or Append.
and LINE INPUT #:Reads from a text file through a bound file number a delimiter-separated set of values
For INPUT()Reads a line from an open text file (opened for Input through a bound file number)
So, while in the first three cases documentation states explicitly to use a text file (although it seems to work also in binary files), there is no such a requirement in the last case.Reads a number of characters from the console, or a bound file/device specified by filenum
Re: Using "PRINT #" and "INPUT ()" on binary files
Ok, found it... in the original Quick Basic help file:
So, I guess Input() is required to work in binary files, even in future versions, if FreeBasic follows the same designINPUT$ Function Details
Syntax
INPUT$(n[,[#]filenumber])
The n is the number of characters (bytes) to read from the file. The
filenumber is the number used to open the file.
If the file is opened for random access, the argument n must be less
than or equal to the record length set by the LEN clause in the OPEN
statement (or less than or equal to 128 if the record length is not
set). If the given file is opened for binary or sequential access,
then n must be less than or equal to 32,767.
If the filenumber is not specified, the characters are read from the
standard input device. (If input has not been redirected, the keyboard
is the standard input device).
You can use the DOS redirection symbols " "(<, >, or >>) or the pipe
symbol (|) to redefine the standard input or standard output for an
executable file created with BASIC. (See your operating system
manual for a complete discussion of redirection and pipes.)
No characters are echoed on the screen. All control characters are
passed through except CTRL+BREAK, which interrupts execution
of the function.
Re: Using "PRINT #" and "INPUT ()" on binary files
dev_file_open.c looks like one of the main (file device) files in the rtl source.
Mostly the "b" string (binary) is used
e.g.
case FB_FILE_MODE_OUTPUT:
/* will create the file if it doesn't exist */
openmask = "wb";
break;
I think the b is always recommended for windows.
I am unsure if the rtl concerning files is still similar to quickbasic, or has been changed over the years, so that's about all I can offer in this thread.
Mostly the "b" string (binary) is used
e.g.
case FB_FILE_MODE_OUTPUT:
/* will create the file if it doesn't exist */
openmask = "wb";
break;
I think the b is always recommended for windows.
I am unsure if the rtl concerning files is still similar to quickbasic, or has been changed over the years, so that's about all I can offer in this thread.
Re: Using "PRINT #" and "INPUT ()" on binary files
Please keep these kinds of comments to a minimum. This has been reported as a possible "personal attack" and I can see that. I assume that this is not the case and it is just a figure of speech that does not translate well.MrSwiss wrote:OK, you seem to be someone, that wants: "to go through a wall, head first".
Print #, and Input() are meant for NONE "binary" file I/O (all else is pure speculation).
You're probably likely, to end up with the face in the mud ...
Re: Using "PRINT #" and "INPUT ()" on binary files
Indeed, I see this in the QB documentation, but by cons nothing about compatibility of 'Print#' and '[Line] Input#' with 'Random/Binary' files.angros47 wrote:Ok, found it... in the original Quick Basic help file:
So, I guess Input() is required to work in binary files, even in future versions, if FreeBasic follows the same designINPUT$ Function Details
Syntax
INPUT$(n[,[#]filenumber])
The n is the number of characters (bytes) to read from the file. The
filenumber is the number used to open the file.
If the file is opened for random access, the argument n must be less
than or equal to the record length set by the LEN clause in the OPEN
statement (or less than or equal to 128 if the record length is not
set).
...
If the developers agree to maintain the current compatibility of 'Input(n As Integer, filenum As Integer) As String' (with 'Random/Binary' files) in the future versions, I can then complete the corresponding page of the FB documentation.
Re: Using "PRINT #" and "INPUT ()" on binary files
Without actually testing every mode on every target platform, here's what I think I can say, with some amount of confidence:fxm wrote:If the developers agree to maintain the current compatibility of 'Input(n As Integer, filenum As Integer) As String' (with 'Random/Binary' files) in the future versions, I can then complete the corresponding page of the FB documentation.
1) GET/PUT/SEEK position argument is by file byte offset, except for RANDOM mode files/devices which is by record number, and depends on record length.
2) GET/PUT will write/read exact bytes only in all modes, except RANDOM which will GET/PUT records
3) PRINT will write strings, subject to CR/CR+LF translation depending on platorm & file mode
4) INPUT # will read strings, subject to CR/CR+LF translataion (shouldn't matter in fb), and delimiters
5) INPUT() will read bytes, similar to GET #
6) Exact device may matter, i.e. file versus COM versus LPT, etc, especially on DOS/WIN where we have written special drivers for each kind of device. On linux, maybe not so much, since most stream operations resolve to C runtime calls.
I'll be honest; I have not tested any claims or behaviours presented in this thread. I'm just commenting on the topic from what (I think) I remember. I know in the past there have been differences between original QB(TM) and freebasic behaviours, especially when it comes to RANDOM files and EOF, etc.
Re: Using "PRINT #" and "INPUT ()" on binary files
I verified for sure that, at least under Windows and DOS (not under Linux, at least in my test) GET# and INPUT() produce different results (and they may also change the position in different ways) if the file has been opened FOR INPUT or FOR BINARY
Re: Using "PRINT #" and "INPUT ()" on binary files
Ah, I see what you are talking about now. dodicat was pretty close. files opened for INPUT are opened with "rt" mode (read, text). GET# and INPUT(), ultimately call fread() in the c runtime. According to windows docs, fread(), when used with files opened in text mode files, CR's are replaced with CR+LF's pairs. Normally, the opposite would occur for OUTPUT, which uses fwrite(), but fbc opens files for APPEND and OUTPUT in c runtime binary mode only.
Here's a test program with output (from windows).
OUTPUT:
Linux wouldn't do the translation CR => CR+LF, so there would be difference there.
Here's a test program with output (from windows).
Code: Select all
sub PrintStringAsHex( t as string, s as string )
print left( t & space(20), 20 );
for i as integer = 1 to len(s)
print hex( asc(mid(s, i, 1)), 2 ); " ";
next
print
end sub
sub ReadFileContents()
dim s as string
open "test.txt" for binary as #1
s = string( lof(1), 0 )
get #1,, s
PrintStringAsHex( "binary+get", s )
close #1
open "test.txt" for binary as #1
s = input( lof(1), #1 )
PrintStringAsHex( "binary+input()", s )
close #1
open "test.txt" for input as #1
s = string( lof(1), 0 )
get #1,, s
PrintStringAsHex( "input+get", s )
close #1
open "test.txt" for input as #1
s = input( lof(1), #1 )
PrintStringAsHex( "input+input()", s )
close #1
end sub
dim s as string
open "test.txt" for binary as #1
s = "free" + chr(13, 10) + "basic" + chr(13, 10)
put #1,,s
PrintStringAsHex( "binary+put", s )
close #1
ReadFileContents()
print
open "test.txt" for output as #1
s = "free" + chr(13) + "basic" + chr(13)
put #1,,s
PrintStringAsHex( "output+put", s )
close #1
ReadFileContents()
print
open "test.txt" for output as #1
s = "free" + chr(13) + "basic" + chr(13)
print #1,s;
PrintStringAsHex( "output+print", s )
close #1
ReadFileContents()
Code: Select all
binary+put 66 72 65 65 0D 0A 62 61 73 69 63 0D 0A
binary+get 66 72 65 65 0D 0A 62 61 73 69 63 0D 0A
binary+input() 66 72 65 65 0D 0A 62 61 73 69 63 0D 0A
input+get 66 72 65 65 0A 62 61 73 69 63 0A 00 00
input+input() 66 72 65 65 0A 62 61 73 69 63 0A
output+put 66 72 65 65 0D 62 61 73 69 63 0D
binary+get 66 72 65 65 0D 62 61 73 69 63 0D
binary+input() 66 72 65 65 0D 62 61 73 69 63 0D
input+get 66 72 65 65 0D 62 61 73 69 63 0D
input+input() 66 72 65 65 0D 62 61 73 69 63 0D
output+print 66 72 65 65 0D 62 61 73 69 63 0D
binary+get 66 72 65 65 0D 62 61 73 69 63 0D
binary+input() 66 72 65 65 0D 62 61 73 69 63 0D
input+get 66 72 65 65 0D 62 61 73 69 63 0D
input+input() 66 72 65 65 0D 62 61 73 69 63 0D