Here, I collect a few annoying pitfalls of the language.
071
is 57?The leading 0
means it's an octal number, so 071
= 7×8+1 = 57, not 71.
This "feature" is annoying: who uses octal numbers these days?
If you want a prefix for octal numbers, make it 'o' instead of '0').
sizeof
(array/pointer), part 1In a 32-bit machine, with a declaration int a[3], *p;
you get,
sizeof(a) = 3×4=12;
but
sizeof(p) = 4 = sizeof a pointer.
sizeof
(array/pointer), part 22D arrays/pointers are even trickier:
with int a[3][3], (*p)[3], **q;
you get,
sizeof(a) = 3×3×sizeof(int); = 36;
sizeof(*p) = 3×sizeof(int) = 12;
sizeof(*q) = 4 = sizeof(void *);
The function parameter is always a pointer,
even if you declare it as an array,
e.g., size_t f(int a[10]) { return sizeof(a); }
yields the size of a pointer = 4, instead of
10×sizeof(int) = 40
.
However
size_t f(int (*pa)[10]) { return sizeof(*pa); }
will give 10×sizeof(int) = 40
.
Example code for the above three points.
fgetc()
returns int
getchar()
, fgetc()
returns an int instead of char,
because −1 means EOF, 0-127 means normal ASCII, 128-255 means non-ASCII code.
So if it's not −1, we could convert
the output as
(char)(unsigned char)c
.
ungetc()
only works onceThe standard only guarantees that the first ungetc()
works, calling it succesively may or may not work.
Alternative 1: implement a buffer yourself.
Alternative 2: use fgetpos()
and fsetpos()
to save and restore a position.
strncpy()
strncpy(s, t, 5);
copies five characters from string t,
but s is not necessarily terminated with a '\0' if string t is too long.
So you should do it manually after the function call like
s[5] = '\0';
and make sure that the string s can contain at least 6 instead 5 characters.
A more elegant solution is:
sprintf(s, "%.5s", t);
strcmp(s, t)
strcmp()
returns 0 if s is equal to t.
It may be natural to write
if (strcmp(s, t)) ...
but it should be
if (strcmp(s, t) == 0) ...
gets()
unsafeAlways use fgets(s, sizeof s, fp)
instead,
even if fp
is stdin
.
†GNU programmers sometimes argue that fgets()
is also unsafe,
if the file is binary and contains a '\0'.
But I usually assume a good text file, so fgets()
works.
printf()
and scanf()
See the printf() page.