Thread: strtod in standard library not working

  1. #1
    Registered User
    Join Date
    Mar 2016
    Posts
    110

    strtod in standard library not working

    The standard C library provides us strtod to convert string to double. I tried this:

    Code:
    int main () {    char* randomPointer;
        printf("%lf", (strtod("123.0 a", &randomPointer)));
        return 0;
    }
    #includes excluded in snippet for brevity.

    Programme returns 0.00000. Any ideas?

  2. #2
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    Edit - nevermind
    Last edited by Vespasian_2; 05-08-2017 at 12:42 PM.

  3. #3
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    The code in the opening post works if I include <stdlib.h> and prints 123 as expected. If I exclude the library, then I get 0.0000.

    I have a much larger project which I wont post here, but in that code, it still prints 0.0000 even after including <stdlib.h>. Could it be that my headers went wonky due to the projects size?

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Vespasian_2 View Post
    The code in the opening post works if I include <stdlib.h> and prints 123 as expected. If I exclude the library, then I get 0.0000.

    I have a much larger project which I wont post here, but in that code, it still prints 0.0000 even after including <stdlib.h>. Could it be that my headers went wonky due to the projects size?
    It's not "the library" that you're excluding if you leave out the header file. The standard library is automatically linked whether or not you include any particular header file. What's missing is the declaration of the function. Without a declaration, a function is assumed to return an int, but strtod returns a double float which is why the value is mangled.

    It's pretty much impossible for us to guess what's wrong with your bigger project. Try putting #include <stdlib.h> right before the function where you use strtod (as a test).

    And don't leave header files out of your posted code! Firstly, it means we have to put them back in to run the code. Secondly, it leaves us guessing if you ever had them in there in the first place, which as you have just learned can change the results.

    Also, always compile with full warnings don't ignore warnings. On gcc, full warnings are given by the flags -Wall -W -pedantic

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Quote Originally Posted by Vespasian_2 View Post
    The code in the opening post works if I include <stdlib.h> and prints 123 as expected. If I exclude the library, then I get 0.0000.

    I have a much larger project which I wont post here, but in that code, it still prints 0.0000 even after including <stdlib.h>. Could it be that my headers went wonky due to the projects size?
    Given your mistakes so far, did you include stdlib.h in the actual file calling strtod(), or did you just scatter stdlib.h into a few random source files in the hope that magic will happen.

    How many warnings are being generated when you compile the code?

    If you're ignoring any "implicit declaration" warnings, then you're just making it worse.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    Thanks guys,

    I will refactor the code so that there are absolutely no warnings then see if it works. Will update soon

  7. #7
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    Quote Originally Posted by Vespasian_2 View Post
    Thanks guys,

    I will refactor the code so that there are absolutely no warnings then see if it works. Will update soon
    No warnings. It now decides to return 0.00000 again

    Code:
    #include <stdio.h>
    #include <stddef.h>
    #include <stdlib.h>
    
    
    int main () {
        char* randomPointer = NULL;
        printf("%lf\n", (strtod("123.023", &randomPointer)));
        return 0;
    }
    Changing it to %f displays a number but using %lf shows 0.00000.

    Baffled....
    Last edited by Vespasian_2; 05-09-2017 at 07:57 AM.

  8. #8
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    There is no difference whatsoever between %lf and %f when used with printf. Basically %f means %lf when used with printf, although they are different when used with scanf.

    So your "problem" makes absolutely no sense whatsoever. Try copying and pasting the code you've just posted. Compile and run it. Does it work? Of course it does!

    randomPointer is an idiotic name. end is better since that's what it represents (a pointer to the end of the part of the string that was converted).

    When printing something, most humans enjoy a newline character after the visible characters.

  9. #9
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    What I am saying is that %lf prints 0.0000 and %f prints the parsed number. If I am to go through numerous forums online they all say ""%lf" is also acceptable under the current standard -- the l is specified as having no effect if followed by the f conversion specifier (among others).".

    But thanks, your post makes sense

  10. #10
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Vespasian_2 View Post
    What I am saying is that %lf prints 0.0000 and %f prints the parsed number.
    Yes. I read your post. I know that's what you said.

    I'm saying that that is impossible.

    If you really are seeing that behavior then you would need to describe every single detail of what you are doing and someone else (with the same system setup) would need to replicate it before anyone would bother spending any time on it, since, like I said, it's impossible on the face of it.

  11. #11
    Registered User
    Join Date
    Mar 2016
    Posts
    110
    So on your system they both print the same?

    I'm using GCC, codeblocks IDE.

  12. #12
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Vespasian_2 View Post
    So on your system they both print the same?
    I'm using GCC, codeblocks IDE.
    Yes. Of course they do. And you haven't even mentioned your operating system. I assume it's windows since you seem happy not to put newlines at the end of your input, which on linux causes the prompt to appear on the same line right after the output. But windows outputs it's own newline so you may not be seeing that annoying effect.

    printf never, ever sees a float. It is impossible to pass printf a float. If you try to pass it a float, the float will be promoted to a double before it is passed. That's the reason that %f is a synonym for %lf for printf (but, crucially, not for scanf!).

    Additionally, if you try to pass a char or a short, they will both be promoted to ints. This is not specific to printf (i.e., it's not a magical function), but is instead specific to variable parameter lists (the ... syntax). We can make our own function with this behavior:
    Code:
    #include <stdio.h>
    #include <stdarg.h>
    
    void func(int n, ...) {
        va_list va;
        va_start(va, n);
    
        // It is invalid to say va_arg(va, float)! You must use double.
        while (n-- > 0) printf("%f ", va_arg(va, double));
        putchar('\n');
    
        va_end(va);
    }
    
    int main() {
        float  f = 123.45f;
        double d = 123.45;
    
        func(1, f);
        func(1, d);
        func(2, f, d);
    
        return 0;
    }
    Try copying and pasting the following code into a new "project" (or whatever it's called) and running it. What are your results?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        printf("%lf\n", strtod("123.023", NULL));  // if you're not using the end pointer, you can just pass NULL
        return 0;
    }

    EDIT: Now that I think about it (and remember!) the old (C89/90) standard didn't have the %lf format spec. So if you are compiling to that standard (which requires adding -std=c89 or -std=c90 to the gcc flags) then maybe that could cause a problem, although it's much more likely to spit out a warning and still work properly. Remember that to get full warnings you need three flags: -Wall -W -pedantic. (-W is a synonym for -Wextra)
    Last edited by algorism; 05-09-2017 at 09:21 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 03-19-2017, 03:18 PM
  2. GUI with Standard Library
    By Sly in forum C Programming
    Replies: 2
    Last Post: 03-13-2009, 05:06 PM
  3. Pi and the standard library
    By FOOTOO in forum C Programming
    Replies: 7
    Last Post: 04-15-2005, 11:23 AM
  4. strtod not working
    By gandalf_bar in forum C++ Programming
    Replies: 3
    Last Post: 03-11-2004, 04:01 AM
  5. C Standard Library
    By JoshG in forum C Programming
    Replies: 2
    Last Post: 07-17-2002, 09:09 AM

Tags for this Thread