printf and stat problem

D

diadia

#include <sys/types.h>
#include <sys/stat.h>
#include "ctype.h"
#include <stdio.h>


int estimateLen(struct stat buf, FILE *fp)
{

size_t _size = buf.st_size / 4;
printf("%d %d\n",buf.st_size,_size); //result is wrong,_size is zero?
printf("%d %d\n",_size,buf.st_size); //result is correct
}

int main(int argc,char*argv[])
{
FILE *fp;
struct stat s;


if (stat(argv[argc-1],&s))
printf("stat error\n");

estimateLen(s,fp);

}


I don't know _size show zero in the first printf function

Is it a bug?
 
W

Walter Roberson

diadia said:
#include <sys/types.h>

That's not standard C. :(
size_t _size = buf.st_size / 4;

Variables names starting with underscore followed by a lower-case
character are, if I recall correctly, reserved for the implementation.
_size could potentially be a macro or expression defined in one of
the non-standard header files you included.
printf("%d %d\n",buf.st_size,_size); //result is wrong,_size is zero?
printf("%d %d\n",_size,buf.st_size); //result is correct

If _size is defined as something, just about any result could show up.
 
J

Jens.Toerring

diadia said:
#include <sys/types.h>
#include <sys/stat.h>

These are non-standard headers.
#include "ctype.h"
#include <stdio.h>
int estimateLen(struct stat buf, FILE *fp)
{
size_t _size = buf.st_size / 4;

Identifiers starting with an underscore are reserved for the implemen-
tation and shouldn't (or may not) be used by normal programs. What
happens if you rename it to e.g. 'size'?
printf("%d %d\n",buf.st_size,_size); //result is wrong,_size is zero?

'size_t' is (normally not an int) but some unsigned integer. Better
cast it to unsigned long and then use "%lu" as the format specifier
(unless you have a C99 compliant compiler and can use "%zu").
printf("%d %d\n",_size,buf.st_size); //result is correct
}

Where's the return statement? You promised to return an int.
int main(int argc,char*argv[])
{
FILE *fp;
struct stat s;
if (stat(argv[argc-1],&s))
printf("stat error\n");

Shouldn't you bail out in that situation instead of calling your
function with a structure that's probably uninitialized?
estimateLen(s,fp);
}

And, again, you need to return something here.
I don't know _size show zero in the first printf function
Is it a bug?

On my system exists a stat() function that perhaps has the same
purpose as the one on your system (assuming you're using some
kind of UNIX - there is no stat() function in standard C and on
my system the 'st_size' member of the stat structure is of type
off_t, which may or may not make a difference) and I can't repro-
duce the error you seem to get.
Regards, Jens
 
M

Martin Ambuhl

diadia said:
#include <sys/types.h>
#include <sys/stat.h>

In spite of the fact that the above are not standard C (normally a red
flag indicating that you have posted to the wrong newsgroup), they are
not relevant to your problem.
#include "ctype.h"

#include <stdio.h>


int estimateLen(struct stat buf, FILE *fp)
{

size_t _size = buf.st_size / 4;

Do not use identifiers beginning with underscores. In this case you
would survive, but it is best not to do things that require you to
remember which exceptional cases are safe. Until you learn a lot more C
than you know now, treat all identifiers beginning with an underscore as
being in the namespace reserved for the implementation.
printf("%d %d\n",buf.st_size,_size); //result is wrong,_size is zero?
printf("%d %d\n",_size,buf.st_size); //result is correct
[... despite your subject line, the non-standard function stat() has
nothing to do with your problem]
I don't know _size show zero in the first printf function
Is it a bug?

It is a bug in your program. %d is the specifier for an int. A size_t
is unsigned (int is signed) and is often larger than an int. Unless you
have a C99 implementation of printf, where a specifier for size_t
exists, you want something like the following, listing in decreasing
safety ('Size' replacing '_size' below)
> printf("%llu\n",(long long unsigned)Size); or
> printf("%lu\n",(long unsigned)Size); or
> printf("%u\n",(unsigned)Size); or
> printf("%d\n",(int)Size);

Using the wrong specifier not only can lead to errors in the
interpretation of a particular variable, but because different sizes
screw up references to subsequent arguments, it can lead to errors in
interpretation of other variables.
 
S

SM Ryan

# int estimateLen(struct stat buf, FILE *fp)
# {
#
# size_t _size = buf.st_size / 4;
# printf("%d %d\n",buf.st_size,_size); //result is wrong,_size is zero?
# printf("%d %d\n",_size,buf.st_size); //result is correct
# }

%d is used to print int, or values widenned to int, like short and char.
If sizeof(buf.st_size)>sizeof(int) or sizeof(_size)>sizeof(int), you need
another format or cast the argument to int.
 
R

Richard Bos

Identifiers starting with an underscore are reserved for the implemen-
tation and shouldn't (or may not) be used by normal programs.

Not quite. Identifiers starting with an underscore and a lower-case
letter are only reserved at file scope. This is such an identifier, and
it has block scope. This makes this declaration legal; it does not make
it a good idea.
My advise, for safety and ease of use, is to always write your own code
as if the rule Jens gives is true. but to be aware that it is a
simplification.

Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top