Issue
I just hit that "problem" : is there a smart way to insert the end of file (ASCII 0) character in a string?
By "smart", I mean something better than
let s = "foo" ^ (String.make 1 (Char.chr 0))
let s = "foo\000"
that is, something which would reflect that we are adding an EOF, not a "mystery char which ascii value is 0".
EDIT: Mmh... indeed I was messing with eof being a char. But anyway, in C you can have
#include <stdio.h>
int main(void)
{
char a = getchar();
if (a = EOF)
printf("eof");
else
printf("not eof");
return 0;
}
Where you can test whether a char is an EOF (and (int) EOF
is -1
, not 0
as I was thinking). And similarly, you can set a char to be EOF, etc..
My question is: Is it possible to have something similar in ocaml ?
Solution
Your C has two errors. First, you assign EOF to a
instead of comparing a
with EOF. Second, getchar()
returns an int. It returns an int expressly so that it can return EOF, a value not representable by a char. Your code (with the first error corrected), which assigns getchar()
s value to a char before testing it, will fail to process a file with a char of value 255 in it:
$ gcc -Wall getchar.c -o getchar
$ echo -e "\xFF" > fake-eof
$ echo " " > space
$ ./getchar < fake-eof
eof
$ ./getchar < space
not eof
The trick with getchar
returning int, of returning a larger type so that your return can include the smaller type and alternately other kinds of information, is a trick that's wholly unnecessary in OCaml due to its more advanced type system. OCaml could have
(* using hypothetical c_getchar, a wrapper for the getchar() in C that returns an int *)
let getchar_opt () =
match c_getchar () with
| -1 -> None
| c -> Some (char_of_int c)
let getchar_exn () =
match c_getchar () with
| -1 -> raise End_of_file
| c -> char_of_int c
type `a ior = EOF | Value of 'a
let getchar_ior () =
match c_getchar_ior () with
| -1 -> EOF
| c -> Value (char_of_int c)
Of course Pervasives.input_char
in OCaml raises an exception on EOF rather than doing one of these other things. If you want a non-exceptional interface, you could wrap input_char
with your own version that catches the exception, or you could - depending on your program - use Unix.read
instead, which returns the number of bytes it was able to read, which is 0 on EOF.
Answered By - Julian Fondren Answer Checked By - Terry (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.