I saw it in a code like this
while(~scanf("%d",&a))
I know that scanf()
has return value,but I can’t understand what does ~
mean
I saw it in a code like this
while(~scanf("%d",&a))
I know that scanf()
has return value,but I can’t understand what does ~
mean
This is a silly trick that relies on EOF
having all its bits set. Since the standard does not guarantee the exact value of EOF, the behavior of this program is platform-dependent.
When scanf
detects end-of-input, it returns EOF
. Standard requires EOF
to be negative. Very often EOF
is set to -1
. When ~
is applied to -1
, you get back a zero, so the loop stops. On platforms with EOF
defined as some other negative number the loop will never stop. Code's behavior also depends on the implementation-defined behavior of ~
with signed values.
You should rewrite the loop as follows:
while (scanf("%d", &a) != EOF) {
...
}
There are a few knowledge tidbits that are needed to explain how this works and what it does.
First: ~
~
is the bitwise NOT
operator. It inverts the bits in a binary number.
ex:
1010111
0101000
Second: scanf()
If you look at the man
pages for scanf()
:
NAME
scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf
...
RETURN VALUE
These functions return the number of input items successfully matched
and assigned, which can be fewer than provided for, or even zero in the
event of an early matching failure.
The value EOF is returned if the end of input is reached before either
the first successful conversion or a matching failure occurs. EOF is
also returned if a read error occurs, in which case the error indicator
for the stream (see ferror(3)) is set, and errno is set indicate the
error.
We can see that when scanf()
is successful, it will return some integer equal to or greater than 0. If it reached EOF
or was otherwise unsuccessful, it will return the (integer) value EOF
.
Third: the trick
If you NOT
most non-zero integers, you will still receive a non-zero value in return.
The exception to this would be a number than when represented in binary would be entirely 1
's:
~11111111 = 00000000 = 0
As it turns out in most computer systems this happens to be the value -1
which just so happens to be the value typically assigned to EOF
So
while(~scanf("%d",&a))
Could be re-written as
while(scanf("%d",&a) != -1)
or
while(scanf("%d",&a) != EOF)