0

I am reading from a file that has numbers (some int and double) and are separated by ','. example: 12.2,55.9,12.5 I separated each number using a strtok() and saved it a pointer. ( I using 'c' NOT c++).

char * num1 = "12.2";
char * num2 = "55.9";
char * num2 = "12.5";

I want to store each number in its own double variable.

I have tired:

double numD1 = atof(num1);
double numD1 = double(num1);
Sudent
  • 15

2 Answers2

6

EDITED to add value invoking errno == ERANGE;, below for illustration

First, in your post you indicated you tried:

char * num1 = "12.2";  
double numD1 = atof(num1); 

This should have worked.

The simplest method is: (as you have already tried)

double x = atof("12.2");

atof()- Converts the initial portion of a string to a double representation.

Better would be:

double x = strtod("12.3", &ptr);

strtod():

The C library function double strtod(const char *str, char **endptr) converts the string pointed to by the argument str to a floating-point number (type double). If endptr is not NULL, a pointer to the character after the last character used in the conversion is stored in the location referenced by endptr. If strtod() could not convert the string because the correct value is outside the range of representable values, then it sets errno to ERANGE (defined in errno.h).

Here is an example of using strtod(); with two inputs: (also illustrates use of errno)

#include <errno.h>

int main ()
{
    char input[] = "10.0 5.0";
    char bad1[] = "0.3e500";
    char bad2[] = "test";
    char *ptr;
    double a, b, c;

    errno = 0;
    a = strtod (input,&ptr);
    if(errno != ERANGE)
    {
        errno = 0;
        b = strtod (ptr,0);
        if(errno != ERANGE)
        {
             printf ("a: %*.2lf\nb: %*.2lf\nQuotient = %*.2lf\n", 12, a, 12, b, 3, a/b);
        }else printf("errno is %d\n", errno);
    } else printf("errno is %d\n", errno);
    
    //bad numeric input     
    errno = 0;
    c = strtod (bad1, &ptr);
    if(errno != ERANGE)
    {
        printf ("Output= %.2lf\n", c);
    } else printf("errno is %d\n", errno);
    
    //text input
    errno = 0;
    c = strtod (bad2, &ptr);
    if(ptr != bad2)
    {
        printf ("Output= %.2lf\n", c);
    } else printf("invalid non-numeric input: \"%s\" \n", ptr);
    getchar();
    
    return 0;
}  
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • 2
    Agree `strtod()` is better than `atof()`. Showing how to use `ptr` and maybe `errno` would improve the answer. – chux - Reinstate Monica Oct 15 '14 at 15:50
  • @chux - thanks. Added note and code illustrating use of errno. – ryyker Oct 15 '14 at 16:34
  • 1
    Note: 1) should `errno=0` prior to `strtod()` as the function does not set `errno = 0` on success. With current code,if `a` or `b` conversions set `errno`, `c` will appear wrong too. 2) If `input==endptr`, then no conversion occurred and `strtod()` returns `0.0`. Certainly a problem worthy of an error message. 3) If `strtod()` underflows, it returns a value about `+/-0.0` or "+/- smallest normalized positive number" and _maybe_ sets `errno = ERANGE`. 4) Given the complexities of robust usage of `strtod()`,suggest spinning off to a helper function. It is better, but not easier. +1 anyways – chux - Reinstate Monica Oct 15 '14 at 18:00
  • 1
    @chux - I started to edit answer to address your comments (very good comment by the way) but then noticed what OP settled for. (see comment in post below) and thought, why go further? However, I did find ***[this interesting post](https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageId=6619179)*** mostly about errno, but also confirming your observation that `strtod()` is ***robust***. (I can think of a few other things it is) – ryyker Oct 15 '14 at 18:24
  • 1
    @ryyker Agree - "this interesting point" reference. Also agree about "why go further?". The key about `strtod(), strtol(), ...` is that they are building blocks for a string to number converter. I find them useful but rarely good stand-alone. [strtol() example](http://stackoverflow.com/a/20269225/2410359) – chux - Reinstate Monica Oct 15 '14 at 18:40
1

For atof to work correctly, you need to include the header file stdlib.h.

Ankush Jain
  • 487
  • 2
  • 14
  • 1
    I found another way an it works for me. 1st) I made a: double x; then I used: "C is the pointer" sscanf(c,"%lf",&x); I then printf("X is %lf\n",x); Thank you !! – Sudent Oct 15 '14 at 16:19