converting string to a double variable in C
Asked Answered
C

8

22

I have written the following code. It should convert a string like "88" to double value 88 and print it

void convertType(char* value)
{
   int i = 0;
   char ch;
   double ret = 0;
   while((ch = value[i])!= '\0')
   {
      ret = ret*10 + (ch - '0');
      i++;
   }
   printf("%d",ret); //or %lf..
}

// input string :88

But it always prints 0. But when I change type of ret to int, it works fine. When the type is float or double, it prints 0. So why am I getting these ambiguous results?

Complex answered 9/4, 2012 at 15:10 Comment(8)
There's no such thing as a String in C ;-)Digestive
"%f" or "%g" (or "%e" for exponential format) is used for both (float) and (double).Because
just forget about the title ..:)Complex
@Digestive it doesn't say String in the title...Renick
@geekosaur: to be more precise, %f is for double-only. When you pass a float as a parameter to a variadic function, it gets promoted from a float to a double.Otoplasty
@Aidanc: The C standard would disagree with you. The first sentence in section 7.1.1 of the C standard, the 'definition of terms' part of the introduction to the standard library, says: A string is a contiguous sequence of characters terminated by and including the first null character. So, as far as the standard is concerned, there are strings.Torticollis
BTW: If you want a slightly faster, smaller version of your loop: for( ; *value != '\0'; ret = 10*ret + *value++ - '0');Otoplasty
@JonathanLefflerm yes, strings exist. But they are not a data type of the language as they are with many other languages. They are merely a convention understood by several functions of the standard library.Refined
C
36

Use sscanf (header stdio.h or cstdio in C++):

char str[] = "12345.56";
double d;

sscanf(str, "%lf", &d);

printf("%lf", d);
Contrayerva answered 9/4, 2012 at 15:13 Comment(3)
I disagree that this is a good answer. It doesn't solve the problem, and there was nothing wrong with OPs loop for parsing a string to a double.Otoplasty
I don't tell that it is a wrong way, but it's reinventing a wheel (as we tell in Poland).Contrayerva
@Otoplasty how isn't this a good answer: It converts a string to a double just fine, how is it not an acceptable answer? If there is something inherently wrong please expound further.Japonica
P
7

You might be able to use atof() it returns a double.

source

Pepito answered 9/4, 2012 at 15:13 Comment(3)
i tried atof and strtod().. Both prints 0...worked only when type of ret changed to intComplex
@Jinu its not the problem with atof or strtod. Check my answerComenius
Also, the link in this answer is broken now.Animus
C
5

But it always prints 0...But when i change type of ret to int ...it works fine...when the type is float or double,it prints zero.

Logic is fine. Just your format specifier is wrong. Change it to %f and all is well!

Comenius answered 9/4, 2012 at 15:16 Comment(0)
Q
1

You should use function "atof" if you want to parse a char* to double.

You should also use the delimiter "%f" to print the double:

More information and example of use can be found here.

Example of use:

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

int main()
{
   float val;
   char str[20];

   strcpy(str, "98993489");
   val = atof(str);
   printf("String value = %s, Float value = %f\n", str, val);

   strcpy(str, "tutorialspoint.com");
   val = atof(str);
   printf("String value = %s, Float value = %f\n", str, val);

   return(0);
}

To print it you must print it as a float:

printf("This is the value in float: %f\n", yourFloatValue);
Quinton answered 20/9, 2016 at 14:59 Comment(1)
The atof function seems to be unreliable in some cases, though.Animus
A
1

converting string to a double variable in C

If overflow is not a concern, yet code wants to detect extra non-white-space text after the numeric text:

// return 1 on success
int convertType(const char* value, double *destination) {
  char sentinel;
  return sscanf(value,"%f %c", destination, &sentinel) == 1;
}

If the sscanf() fails to find a double, the return value of sscanf() will be EOF or 0.

If the sscanf() finds non-white-space text after numeric text, it will return 2.

If only a double is scanned, without extra, sscanf() returns 1. Leading and trailing white-spaces are OK.

Example:

double x;
if (convertType(some_string, &x)) {
  printf("%.17e\n", x);  // or whatever FP format you like
} else {
  puts("Failed");
}
Angloamerican answered 10/8, 2017 at 2:53 Comment(0)
D
0

This works for me:

double stod(const char* s); //declaration

double d = stod(row[0]); //call


double stod(const char* s){    //definition
    double rez = 0, fact = 1;
    if (*s == '-'){
        s++;
        fact = -1;
    };
    for (int point_seen = 0; *s; s++){
        if (*s == '.'){
            point_seen = 1;
            continue;
        };
        int d = *s - '0';
        if (d >= 0 && d <= 9){
            if (point_seen) fact /= 10.0f;
            rez = rez * 10.0f + (float)d;
        };
    };
    return rez * fact;
};
Discrown answered 20/6, 2020 at 7:10 Comment(1)
Consider adding some details about how your code works?Quixote
F
-2

The following code works for me.

#include <stdio.h>

void convertType(char* value);

int main(int argc, char *argv[]) {
    char *str="0929";
    convertType(str);

    return  0;
}

void convertType(char* value) {
    double ret = 0;

    while(*value != '\0') {
        ret = ret*10 +(*value - '0');
        value++;
    }

    fprintf(stdout, "value: %f\n", ret);
}
Flann answered 9/4, 2012 at 17:22 Comment(1)
This isn't exactly got to give a good answer for the input -.00314159E+003, is it?Torticollis
R
-2
#define ZERO 48
#define NINE 57
#define MINUS 45
#define DECPNT 46

long strtolng_n(char* str, int n)
{
    int sign = 1;
    int place = 1;
    long ret = 0;

    int i;
    for (i = n-1; i >= 0; i--, place *= 10)
    {
        int c = str[i];
        switch (c)
        {
            case MINUS:
                if (i == 0) sign = -1;
                else return -1;
                break;
            default:
                if (c >= ZERO && c <= NINE) ret += (c - ZERO) * place;
                else return -1;
        }
    }

    return sign * ret;
}

double _double_fraction(char* str, int n)
{
    double place = 0.1;
    double ret = 0.0;

    int i;
    for (i = 0; i < n; i++, place /= 10)
    {
        int c = str[i];
        ret += (c - ZERO) * place;
    }
    return ret;
}
double strtodbl(char* str)
{
    int n = 0;
    int sign = 1;
    int d = -1;
    long ret = 0;

    char* temp = str;
    while (*temp != '\0')
    {
        switch (*temp)
        {
            case MINUS:
                if (n == 0) sign = -1;
                else return -1;
                break;
            case DECPNT:
                if (d == -1) d = n;
                else return -1;
                break;
            default:
                if (*temp < ZERO && *temp > NINE) return -1;
        }
        n++;
        temp++;
    }

    if (d == -1)
    {
        return (double)(strtolng_n(str, n));
    }
    else if (d == 0)
    {
        return _double_fraction((str+d+1), (n-d-1));
    }
    else if (sign == -1 && d == 1)
    {
        return (-1)*_double_fraction((str+d+1), (n-d-1));
    }
    else if (sign == -1)
    {
        ret = strtolng_n(str+1, d-1);
        return (-1) * (ret + _double_fraction((str+d+1), (n-d-1)));
    }
    else
    {
        ret = strtolng_n(str, d);
        return ret + _double_fraction((str+d+1), (n-d-1));
    }
}
Racial answered 12/9, 2013 at 11:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.