printf and stat problem

Discussion in 'C Programming' started by diadia, May 13, 2005.

  1. diadia

    diadia Guest

    #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?

    --
    Origin: ¤¤¥¿¤j¾Ç£»GAIS¤ý´Â  gais.twbbs.org 
    Author: diadia ±q gais5.cs.ccu.edu.tw µoªí
     
    diadia, May 13, 2005
    #1
    1. Advertising

  2. In article <4IB9ah$>,
    diadia <> wrote:

    >#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.
    --
    Beware of bugs in the above code; I have only proved it correct,
    not tried it. -- Donald Knuth
     
    Walter Roberson, May 13, 2005
    #2
    1. Advertising

  3. diadia

    -berlin.de Guest

    diadia <> wrote:
    > #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
    --
    \ Jens Thoms Toerring ___ -berlin.de
    \__________________________ http://www.toerring.de
     
    -berlin.de, May 13, 2005
    #3
  4. diadia wrote:
    > #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"


    Note that <ctype.h> is a standard header; using the form above may cause
    you a headache.

    > #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.
     
    Martin Ambuhl, May 13, 2005
    #4
  5. diadia

    SM Ryan Guest

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

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    You face forward, or you face the possibility of shock and damage.
     
    SM Ryan, May 14, 2005
    #5
  6. diadia

    Richard Bos Guest

    -berlin.de wrote:

    > diadia <> wrote:
    >
    > > 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.


    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
     
    Richard Bos, May 17, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Steven T. Hatton
    Replies:
    3
    Views:
    9,746
    Pete Becker
    Jun 2, 2005
  2. Patrick Useldinger

    os.stat('<filename>')[stat.ST_INO] on Windows

    Patrick Useldinger, Feb 27, 2005, in forum: Python
    Replies:
    6
    Views:
    1,210
    =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
    Mar 3, 2005
  3. Magesh
    Replies:
    3
    Views:
    462
    Gordon Burditt
    Oct 5, 2007
  4. Rolf Krüger
    Replies:
    2
    Views:
    636
    Ian Collins
    Mar 12, 2008
  5. ruck
    Replies:
    10
    Views:
    1,293
Loading...

Share This Page