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
Closed

scanf %s processing #4594

vicuna opened this issue Aug 5, 2008 · 2 comments
Assignees

Comments

@vicuna
Copy link

vicuna 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
Copy link
Author

vicuna 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
Copy link
Author

vicuna 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants