Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scanf %s processing #4594

Closed
vicuna opened this Issue Aug 5, 2008 · 2 comments

Comments

Projects
None yet
2 participants
@vicuna
Copy link
Collaborator

commented Aug 5, 2008

Original bug ID: 4594
Reporter: smitley
Assigned to: @pierreweis
Status: closed (set by @pierreweis on 2009-04-29T18:39:18Z)
Resolution: fixed
Priority: normal
Severity: minor
Version: 3.11+dev
Fixed in version: 3.10.0
Category: -for Caml light use https://github.com/camllight/camllight/issues

Bug description

The following program:

let fd = open_in "tst"
let printit s =
Printf.printf "read %d %s\n" (String.length s) s;;
Scanf.fscanf fd "%s" printit;;
Scanf.fscanf fd "%s" printit;;

when run on the tst file with contents:
xxx yyy

produces the following output:
read 3 xxx
read 0

Ocaml versions prior to 3.10 produced the output:
read 3 xxx
read 3 yyy

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

commented Sep 8, 2008

Comment author: @pierreweis

The behaviour you observed is conformant to the specification:

%s: reads a string argument that spreads as much as possible, until the
following bounding condition holds: a whitespace has been found, a
scanning indication has been encountered, or the end-of-input has been
reached.
Hence, this conversion always succeeds: it returns an empty
string if the bounding condition holds when the scan begins.

The first scan returns "xxx" and ends on the space character. The second scan then starts on this space character; according to the specification, it stops immediately and returns an empty string.

If you want to skip the space, you simply have to mention it in the format: if the first format is "%s " then the second scan starts after the space (alternatively, the second scan may be " %s" to skip the space before scanning the second string).

Furthermore, as mentioned in the documentation, the usage of fscanf is kind of picky:

To avoid confusion, consider using [bscanf] with an explicitly created
scanning buffer. Use for instance [Scanning.from_file fname], to allocate
the scanning buffer reading from file [fname] once and for all.

Therefore, I would suggest you avoid using fscanf as much as possible and use bscanf instead (let ib = Scanf.Scanning.from_file "tst" ...).

As you mentioned, Ocaml versions prior to 3.10 produced a different output; in fact, the scanner always skipped blanks after a %s specification; this was confusing in case of reading a file one line at a time, since reading the last field of a line would silently skip any amount of empty lines, thus preventing the detection and proper treatment of empty lines by the programmer.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 29, 2009

Comment author: @pierreweis

This is not a bug, but a better behaviour to properly handle end of file conditions and empty lines.

@vicuna vicuna closed this Apr 29, 2009

@vicuna vicuna added the caml-light label Mar 14, 2019

@vicuna vicuna added the bug label Mar 19, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.