Format problem with sprintf

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Henryk

    #1

    Format problem with sprintf

    Hey there,

    I have some problems with the following code snippet on a Virtex-4
    PowerPC with a GCC based compiler

    char chData[6];

    sprintf(&chData[0], "%+05.0f", -0.038f); --I get "-000" ???
    sprintf(&chData[0], "%+05.0f", -0.380f); --I get "-000" ???
    sprintf(&chData[0], "%+05.0f", -3.800f); --I get "-0004" ok
    sprintf(&chData[0], "%+05.0f", +0.038f); --I get "+000" ???
    sprintf(&chData[0], "%+05.0f", +0.380f); --I get "+000" ???
    sprintf(&chData[0], "%+05.0f", +3.800f); --I get "+0004" ok

    I would expect to get always a string with the length of 5 but
    sometimes I get only 4 chars back. Is this a compiler bug?

    In Visual Studio I get always 5 chars back.

    Thank you

    Henryk

  • Mike Wahler

    #2
    Re: Format problem with sprintf


    "Henryk" <henryk.mueller @gmx.dewrote in message
    news:1155909331 .522909.254710@ i42g2000cwa.goo glegroups.com.. .
    Hey there,
    >
    I have some problems with the following code snippet on a Virtex-4
    PowerPC with a GCC based compiler
    >
    char chData[6];
    >
    sprintf(&chData[0], "%+05.0f", -0.038f); --I get "-000" ???
    sprintf(&chData[0], "%+05.0f", -0.380f); --I get "-000" ???
    sprintf(&chData[0], "%+05.0f", -3.800f); --I get "-0004" ok
    sprintf(&chData[0], "%+05.0f", +0.038f); --I get "+000" ???
    sprintf(&chData[0], "%+05.0f", +0.380f); --I get "+000" ???
    sprintf(&chData[0], "%+05.0f", +3.800f); --I get "+0004" ok
    >
    I would expect to get always a string with the length of 5 but
    sometimes I get only 4 chars back. Is this a compiler bug?
    >
    In Visual Studio I get always 5 chars back.
    Me too (VC++ 2005 Express). Perhaps there is a problem with
    your compiler. Try checking its support resources. We only
    discuss the C language itself here, not specific implementations .

    FWIW, I've included my test program and its output (which looks
    correct) below.


    -Mike

    #include <string.h>
    #include <stdio.h>

    int main(void)
    {
    char chData[6];

    sprintf(&chData[0], "%+05.0f", -0.038f); /* --I get "-000" ??? */
    printf("%s\n", chData);

    sprintf(&chData[0], "%+05.0f", -0.380f); /* --I get "-000" ??? */
    printf("%s\n", chData);

    sprintf(&chData[0], "%+05.0f", -3.800f); /* --I get "-0004" ok */
    printf("%s\n", chData);

    sprintf(&chData[0], "%+05.0f", +0.038f); /* --I get "+000" ??? */
    printf("%s\n", chData);

    sprintf(&chData[0], "%+05.0f", +0.380f); /* --I get "+000" ??? */
    printf("%s\n", chData);

    sprintf(&chData[0], "%+05.0f", +3.800f); /* --I get "+0004" ok */
    printf("%s\n", chData);

    return 0;
    }

    Output:

    -0000
    -0000
    -0004
    +0000
    +0000
    +0004

    -Mike


    Comment

    • Christopher Benson-Manica

      #3
      Re: Format problem with sprintf

      Mike Wahler <mkwahler@mkwah ler.netwrote:
      Me too (VC++ 2005 Express). Perhaps there is a problem with
      your compiler. Try checking its support resources. We only
      discuss the C language itself here, not specific implementations .
      I do think it's on-topic to essentially ask whether the behavior of a
      particular implementation is conformant; in this case, the answer WRT
      OP's implementation is presumably "no". Not that VC++ should be held
      up as a standard of correctness of course :-)

      --
      C. Benson Manica | I *should* know what I'm talking about - if I
      cbmanica(at)gma il.com | don't, I need to know. Flames welcome.

      Comment

      • Martin Ambuhl

        #4
        Re: Format problem with sprintf

        Henryk wrote:
        Hey there,
        >
        I have some problems with the following code snippet on a Virtex-4
        PowerPC with a GCC based compiler
        I don't know what a "Gcc based compiler" means. My gcc compiler does
        not reproduce the behavior you report. The behavior you report is not,
        in any case, a question of the compiler but of a supplied library.
        Replace your version of the C library with one that does not have broken
        *printf functions.
        char chData[6];
        >
        sprintf(&chData[0], "%+05.0f", -0.038f); --I get "-000" ???
        sprintf(&chData[0], "%+05.0f", -0.380f); --I get "-000" ???
        sprintf(&chData[0], "%+05.0f", -3.800f); --I get "-0004" ok
        sprintf(&chData[0], "%+05.0f", +0.038f); --I get "+000" ???
        sprintf(&chData[0], "%+05.0f", +0.380f); --I get "+000" ???
        sprintf(&chData[0], "%+05.0f", +3.800f); --I get "+0004" ok
        >
        I would expect to get always a string with the length of 5 but
        sometimes I get only 4 chars back. Is this a compiler bug?
        >
        In Visual Studio I get always 5 chars back.
        The following code (and a version with the silly "&chData[0]" for plain
        "chData") give, with gcc, the output following it.

        #include <stdio.h>
        int main(void)
        {
        char chData[6];

        sprintf(chData, "%+05.0f", -0.038f);
        printf("%s\n", chData);
        sprintf(chData, "%+05.0f", -0.380f);
        printf("%s\n", chData);
        sprintf(chData, "%+05.0f", -3.800f);
        printf("%s\n", chData);
        sprintf(chData, "%+05.0f", +0.038f);
        printf("%s\n", chData);
        sprintf(chData, "%+05.0f", +0.380f);
        printf("%s\n", chData);
        sprintf(chData, "%+05.0f", +3.800f);
        printf("%s\n", chData);
        return 0;
        }


        -0000
        -0000
        -0004
        +0000
        +0000
        +0004

        Comment

        • Robert Gamble

          #5
          Re: Format problem with sprintf

          Henryk wrote:
          Hey there,
          >
          I have some problems with the following code snippet on a Virtex-4
          PowerPC with a GCC based compiler
          >
          char chData[6];
          >
          sprintf(&chData[0], "%+05.0f", -0.038f); --I get "-000" ???
          sprintf(&chData[0], "%+05.0f", -0.380f); --I get "-000" ???
          sprintf(&chData[0], "%+05.0f", -3.800f); --I get "-0004" ok
          sprintf(&chData[0], "%+05.0f", +0.038f); --I get "+000" ???
          sprintf(&chData[0], "%+05.0f", +0.380f); --I get "+000" ???
          sprintf(&chData[0], "%+05.0f", +3.800f); --I get "+0004" ok
          >
          I would expect to get always a string with the length of 5 but
          sometimes I get only 4 chars back. Is this a compiler bug?
          >
          In Visual Studio I get always 5 chars back.
          The output you describe in your example is not Standard conforming. As
          for whether this is a compiler issue or a library implementation issue,
          try compiling with the gcc option --no-builtin-sprintf and see if you
          get the same results; if you do it is a libc issue, otherwise it is an
          issue with the gcc built-in function (or else they are both broken).

          Robert Gamble

          Comment

          • jacob navia

            #6
            Re: Format problem with sprintf

            Henryk wrote:
            Hey there,
            >
            I have some problems with the following code snippet on a Virtex-4
            PowerPC with a GCC based compiler
            >
            char chData[6];
            >
            sprintf(&chData[0], "%+05.0f", -0.038f); --I get "-000" ???
            sprintf(&chData[0], "%+05.0f", -0.380f); --I get "-000" ???
            sprintf(&chData[0], "%+05.0f", -3.800f); --I get "-0004" ok
            sprintf(&chData[0], "%+05.0f", +0.038f); --I get "+000" ???
            sprintf(&chData[0], "%+05.0f", +0.380f); --I get "+000" ???
            sprintf(&chData[0], "%+05.0f", +3.800f); --I get "+0004" ok
            >
            I would expect to get always a string with the length of 5 but
            sometimes I get only 4 chars back. Is this a compiler bug?
            >
            In Visual Studio I get always 5 chars back.
            >
            Thank you
            >
            Henryk
            >
            I tested it with lcc-win32 and got the same results as with
            MSVC.

            Using gcc under linux I get the same results as MSVC
            and lcc-win32.

            gcc -v gives:
            Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux-gnu/2.96/specs
            gcc version 2.96 20000731 (Mandrake Linux 8.2 2.96-0.76mdk)

            In another linux machine I got the same result.
            gcc -v gives in that machine:
            Using built-in specs.
            Target: i386-redhat-linux
            Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
            --infodir=/usr/share/info --enable-shared --enable-threads=posix
            --enable-checking=releas e --with-system-zlib --enable-__cxa_atexit
            --disable-libunwind-exceptions --enable-libgcj-multifile
            --enable-languages=c,c++ ,objc,java,f95, ada --enable-java-awt=gtk
            --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
            --host=i386-redhat-linux
            Thread model: posix
            gcc version 4.0.1 20050727 (Red Hat 4.0.1-5)


            I think this is not a gcc problem

            Comment

            • Henryk

              #7
              Re: Format problem with sprintf

              The following code (and a version with the silly "&chData[0]" for plain
              "chData") give, with gcc, the output following it.
              The "silly" &chData[0] is used to avoid compiler errors/warnings on
              higher warning levels (something like casting array to pointer
              warning). Of course I could use some static_cast too to avoid the
              warning. But that takes longer to write... ;o)

              Greets

              Henryk

              Comment

              • Henryk

                #8
                Re: Format problem with sprintf


                Christopher Benson-Manica schrieb:
                Mike Wahler <mkwahler@mkwah ler.netwrote:
                >
                Me too (VC++ 2005 Express). Perhaps there is a problem with
                your compiler. Try checking its support resources. We only
                discuss the C language itself here, not specific implementations .
                >
                I do think it's on-topic to essentially ask whether the behavior of a
                particular implementation is conformant; in this case, the answer WRT
                OP's implementation is presumably "no". Not that VC++ should be held
                up as a standard of correctness of course :-)

                Thank you. I will report this possible bug to Xilinx.

                Henryk

                Comment

                • Ben Pfaff

                  #9
                  Re: Format problem with sprintf

                  "Henryk" <henryk.mueller @gmx.dewrites:
                  >The following code (and a version with the silly "&chData[0]" for plain
                  >"chData") give, with gcc, the output following it.
                  >
                  The "silly" &chData[0] is used to avoid compiler errors/warnings on
                  higher warning levels (something like casting array to pointer
                  warning).
                  If chData is declared as array of char, then &chData[0] and
                  chData have the same type and value. It is surprising that a
                  compiler would warn about the former and not the latter.
                  Of course I could use some static_cast too to avoid the
                  warning. But that takes longer to write... ;o)
                  We discuss C here. C doesn't have static_cast.
                  --
                  Just another C hacker.

                  Comment

                  • CBFalconer

                    #10
                    Re: Format problem with sprintf

                    Henryk wrote:
                    >
                    >The following code (and a version with the silly "&chData[0]" for
                    >plain "chData") give, with gcc, the output following it.
                    >
                    The "silly" &chData[0] is used to avoid compiler errors/warnings on
                    higher warning levels (something like casting array to pointer
                    warning). Of course I could use some static_cast too to avoid the
                    warning. But that takes longer to write... ;o)
                    Please don't remove attribution lines for material you quote.
                    Attribution lines are the ones that say "whozit wrote:".

                    chData and &chData[0] are entirely different things. In some cases
                    the passed specification for each may be identical, but that is a
                    coincidence, not a necessity.

                    chData is (presumably) an array of some type. &chData[0] is a
                    pointer to the first item in that array. The difference will be
                    dramatic if you simply display:

                    printf("sz(chDa ta)=%ld, sz(&chData[0]=%ld\n",
                    (long)sizeof(ch Data), (long)sizeof(&c hData[0]));

                    --
                    Chuck F (cbfalconer@yah oo.com) (cbfalconer@mai neline.net)
                    Available for consulting/temporary embedded and systems.
                    <http://cbfalconer.home .att.netUSE maineline address!


                    Comment

                    • Martin Ambuhl

                      #11
                      Re: Format problem with sprintf

                      Henryk wrote:
                      >The following code (and a version with the silly "&chData[0]" for plain
                      >"chData") give, with gcc, the output following it.
                      >
                      The "silly" &chData[0] is used to avoid compiler errors/warnings on
                      higher warning levels (something like casting array to pointer
                      warning). Of course I could use some static_cast too to avoid the
                      warning. But that takes longer to write... ;o)
                      Henryk, who is a Googlegroups (ab)user, has kept from you the context,
                      which was my substitution (in compilable code) of
                      sprintf(chData, "%+05.0f", -0.038f);
                      for his (in uncompilable single lines)
                      sprintf(&chData[0], "%+05.0f", -0.038f); --I get "-000" ???
                      where he has defined
                      char chData[6];

                      While your compiler is free to issue whatever bogus diagnostics its
                      writers want it to, no sane writer of a C compiler would issue one in
                      this case. It is more likely that
                      a) your compiler is broken or
                      b) your compiler is not a C compiler (and so broken for compiling C).
                      In fact, your reference to the completely undefined identifier from the
                      programmer's namespace of "static_cas t" suggests that you are using a
                      C++ compiler. If you continue to have C++ questions, the newsgroup for
                      that different language is <news:comp.lang .c++>. This newsgroup is for
                      C, and none of your comments is relevant to that language.

                      Comment

                      • Henryk

                        #12
                        Re: Format problem with sprintf


                        Martin Ambuhl schrieb:
                        Henryk wrote:
                        The following code (and a version with the silly "&chData[0]" for plain
                        "chData") give, with gcc, the output following it.
                        The "silly" &chData[0] is used to avoid compiler errors/warnings on
                        higher warning levels (something like casting array to pointer
                        warning). Of course I could use some static_cast too to avoid the
                        warning. But that takes longer to write... ;o)
                        >
                        Henryk, who is a Googlegroups (ab)user, has kept from you the context,
                        which was my substitution (in compilable code) of
                        sprintf(chData, "%+05.0f", -0.038f);
                        for his (in uncompilable single lines)
                        sprintf(&chData[0], "%+05.0f", -0.038f); --I get "-000" ???
                        where he has defined
                        char chData[6];
                        >
                        While your compiler is free to issue whatever bogus diagnostics its
                        writers want it to, no sane writer of a C compiler would issue one in
                        this case. It is more likely that
                        a) your compiler is broken or
                        b) your compiler is not a C compiler (and so broken for compiling C).
                        In fact, your reference to the completely undefined identifier from the
                        programmer's namespace of "static_cas t" suggests that you are using a
                        C++ compiler. If you continue to have C++ questions, the newsgroup for
                        that different language is <news:comp.lang .c++>. This newsgroup is for
                        C, and none of your comments is relevant to that language.
                        I asked the C newsgroup because sprintf is part of ANSI C. Sorry for
                        the fauxpas with the static_cast. I usually write C++ code. And even if
                        it is a C++ compiler sprintf should behave according to ANSI C.

                        Henryk

                        Comment

                        • Martin Ambuhl

                          #13
                          Re: Format problem with sprintf

                          Henryk wrote (in response to my comments which I have snipped away):
                          >Henryk wrote:
                          >>>The following code (and a version with the silly "&chData[0]" for plain
                          >>>"chData") give, with gcc, the output following it.
                          >>The "silly" &chData[0] is used to avoid compiler errors/warnings on
                          >>higher warning levels (something like casting array to pointer
                          >>warning). Of course I could use some static_cast too to avoid the
                          >>warning. But that takes longer to write... ;o)
                          I asked the C newsgroup because sprintf is part of ANSI C. Sorry for
                          the fauxpas with the static_cast. I usually write C++ code. And even if
                          it is a C++ compiler sprintf should behave according to ANSI C.
                          You are confused. The question of whether '&chData[0]' is somehow
                          preferable as the first argument to sprintf to the straight-forward,
                          100% legal C approach of using unadorned 'chData' has nothing to do with
                          the way sprintf behaves. If unadorned 'chData' leads to legitimate
                          warnings from your compiler, it is because your compiler has some
                          restriction that is completely non-C on arguments.

                          Now, the current version of C, now zeven years old, has this as the
                          prototype for sprintf:
                          int sprintf(char * restrict s, const char * restrict format, ...);

                          If the language that your compiler is using does not understand
                          'restrict', then it clearly cannot handle a type of 'char * restrict'.
                          In fact, C++ does not know anything about 'restrict', so must use the
                          older form of sprintf. if it uses a C version at all. That prototype is
                          int sprintf(char *s, const char *format, ...);
                          If your compiler does not accept unadorned 'chData' ( declared as a
                          char[6], in your case) as appropriate for a parameter of type 'char *',
                          it will reject it for _all_ such functions, whether they are part of the
                          library or written by you. This has _nothing_ to do with sprintf except
                          for the types of arguments. If you are using C++ and it is broken in
                          this way, so much the worse for C++ and those forced to use it.


                          Comment

                          Working...