# Converting a char\* to a double in C

**URL:** <https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229>\
**Category:** Factual Questions\
**Created:** [March 9, 2004, 3:07am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229 "2004-03-09T03:07:24Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hauky](https://avatars.discourse-cdn.com/v4/letter/h/0ea827/32.png) [@Hauky](https://boards.straightdope.com/u/Hauky)\
**Post date:** [March 9, 2004, 3:07am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/1 "2004-03-09T03:07:24Z")

</div>

Just for background, I’m trying to write a scientific calculator in C for this here school project. We have to convert an equation taken from an input file into postfix, and then go on and do whatever to it. We’re provided with a file that includes nextToken(FILE\*), which takes the next “token” from the file, be it a number, operator, parenthesis or what have you. The problem is that it only returns it as a char\*, and we have to figure out what exactly it is before we put it into the result.

I figure the best way is to see if it’s a number first. I’m trying this with strtod(), and seeing if the end pointer set by it is different from the pointer to the token string, which should mean that _something_ was converted, and thus that a number was found. (We can also use PI and E in our equations, so that’s what’s going on with those.)

```auto

double operand = 0.0;
char *token;
token = (char*) malloc(20);

while (token = (char*) nextToken(fp)) {
   char *pp = 0;
   if (!strcmp(token, "PI"))
      operand = M_PI;
   else if (!strcmp(token, "E"))
      operand = M_E;
   else
      operand = strtod(token, &pp);
   if ( **pp != token** ) {
      /* do crap */
   }
}

```

My problem is the bolded code: it makes a segmentation fault happen. Commenting that part out makes the whole thing work, and printf()ing pp and token with %p will even show the right addresses, depending on what I know is going into token. Judging from a combination of my own learning and Google searches, it _should_ work. It just doesn’t. Am I confused about pointers again?

(I even tried comparing the strlen() of pp and token, thinking that they would be the same if no conversion happened. No dice, but hey, it was worth a shot.)

---

<div class="post-metadata">

**Author:** ![tracer](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/tracer/32/20578_2.png) [@tracer](https://boards.straightdope.com/u/tracer)\
**Post date:** [March 9, 2004, 3:26am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/2 "2004-03-09T03:26:08Z")

</div>

The **only** way that “if (pp != token)” could possibly cause a segmentation fault is if something smashed the stack so that the addresses of either pp or token were off in never-never land.

Note that some debuggers will point to the NEXT statement AFTER the one that crashed when indicating a segment fault. You sure it’s not the “operand = strtod(token, &pp);” statement that’s crashing? (If worse comes to worst, try compiling with optimizations turned off. Optimization bugs are known to exist here and there.)

---

<div class="post-metadata">

**Author:** ![Cleophus](https://avatars.discourse-cdn.com/v4/letter/c/a88e57/32.png) [@Cleophus](https://boards.straightdope.com/u/Cleophus)\
**Post date:** [March 9, 2004, 3:54am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/3 "2004-03-09T03:54:29Z")

</div>

I’m seeing a problem with the malloc() call. You need to check and make sure the pointer returned by malloc() is not NULL. malloc() returns such if it is unable to allocate the requested memory. If you’re getting a null pointer back, and using it anyway, all sorts of weird stuff can happen. Other than that, it looks like it should work.

Like **tracer** , I can’t see how a simple comparison statement can cause a crash under normal circumstances. Even if the pointers are pointing to strange memory locations, simply looking (not using) at the pointer’s value shouldn’t cause a crash, unless stuff was screwed up before that.

---

<div class="post-metadata">

**Author:** ![Jeff\_Lichtman](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/jeff_lichtman/32/1531_2.png) [@Jeff\_Lichtman](https://boards.straightdope.com/u/Jeff_Lichtman)\
**Post date:** [March 9, 2004, 5:16am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/4 "2004-03-09T05:16:56Z")

</div>

I notice that you malloc some memory and promptly discard it. This is a memory leak. While this (probably) isn’t the cause of your seg fault, you will want to do something about it.

---

<div class="post-metadata">

**Author:** ![Omphaloskeptic](https://avatars.discourse-cdn.com/v4/letter/o/bcef8e/32.png) [@Omphaloskeptic](https://boards.straightdope.com/u/Omphaloskeptic)\
**Post date:** [March 9, 2004, 6:27am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/5 "2004-03-09T06:27:42Z")

</div>

I also don’t see any way for the comparison itself to cause a segfault. But note that if the input token is E or PI then pp is still 0 at the bolded line. Since token!=0, the /_do crap_/ will be executed. If you try to use \*pp then you will get a segfault.

---

<div class="post-metadata">

**Author:** ![panamajack](https://avatars.discourse-cdn.com/v4/letter/p/47e85d/32.png) [@panamajack](https://boards.straightdope.com/u/panamajack)\
**Post date:** [March 9, 2004, 9:04am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/6 "2004-03-09T09:04:44Z")

</div>

You shouldn’t be initializing pp to 0. It ought not to work because of this (bolding added):

> [@](#):
>
> double strtod (const char \*s, char \*\*endp)  
> _strtod_ converts the prefix of _s_ to double, ignoring leading white space; it stores a pointer to any unconverted suffix in \*endp **unless endp is NULL**. . . .  
> (K&R 2nd ed. p.251)

This doesn’t really explain why the seg fault, unless it is occurring in the strtod call (and your stdlib is reacting oddly to the NULL ptr).

---

<div class="post-metadata">

**Author:** ![Jeff\_Lichtman](https://sea3.discourse-cdn.com/straightdope/user_avatar/boards.straightdope.com/jeff_lichtman/32/1531_2.png) [@Jeff\_Lichtman](https://boards.straightdope.com/u/Jeff_Lichtman)\
**Post date:** [March 9, 2004, 9:10am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/7 "2004-03-09T09:10:08Z")

</div>

> [@panamajack](#):
>
> You shouldn’t be initializing pp to 0. . .

I disagree. The second argument he passes to strtod() is &pp, not pp. Since &pp is not null, strtod should fill pp with the address of the unconverted suffix.

---

<div class="post-metadata">

**Author:** ![JohnClay](https://avatars.discourse-cdn.com/v4/letter/j/c37758/32.png) [@JohnClay](https://boards.straightdope.com/u/JohnClay)\
**Post date:** [March 9, 2004, 11:07am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/8 "2004-03-09T11:07:10Z")

</div>

> [@Hauky](#):
>
> _while (token = (char) nextToken(fp))_\*

Your problem may be that the while loop doesn’t work properly (usually it would involve “while (x **==** whatever)”). That while loop might go on forever due to whatever boolean value the thing after the while evaluates to. nextToken(fp) might cause pp to go past the memory that’s allocated to itself. Just a wild guess.

You could do this:

Insert “token = (char\*) nextToken(fp);” before the while loop, and right at the end of the while loop. Then make the while loop say “while (token != NULL)” or maybe “while (token)”. Just a guess.

---

<div class="post-metadata">

**Author:** ![JohnClay](https://avatars.discourse-cdn.com/v4/letter/j/c37758/32.png) [@JohnClay](https://boards.straightdope.com/u/JohnClay)\
**Post date:** [March 9, 2004, 11:13am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/9 "2004-03-09T11:13:05Z")

</div>

Corrections:

My first point about the while loop is that your loop is in the form “while (x = y)” but it should be “while (x == y)” (or a similar conditional statement, e.g. involving \>, \<, or != )

Also, “token = (char\*) nextToken(fp)” might cause **token** to go past the memory that’s allocated to itself.

---

<div class="post-metadata">

**Author:** ![Capt.Ridley\_s\_Shooting\_Party](https://avatars.discourse-cdn.com/v4/letter/c/cc9497/32.png) [@Capt.Ridley\_s\_Shooting\_Party](https://boards.straightdope.com/u/Capt.Ridley_s_Shooting_Party)\
**Post date:** [March 9, 2004, 11:21am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/10 "2004-03-09T11:21:03Z")

</div>

John, the while loop will cease looping when the value returned by nexToken is NULL, I think.

---

<div class="post-metadata">

**Author:** ![JohnClay](https://avatars.discourse-cdn.com/v4/letter/j/c37758/32.png) [@JohnClay](https://boards.straightdope.com/u/JohnClay)\
**Post date:** [March 9, 2004, 11:22am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/11 "2004-03-09T11:22:39Z")

</div>

Another idea:

What if you try replacing that “pp != token” with a 1 or 0? (one means “true” and one means “false”)

---

<div class="post-metadata">

**Author:** ![JohnClay](https://avatars.discourse-cdn.com/v4/letter/j/c37758/32.png) [@JohnClay](https://boards.straightdope.com/u/JohnClay)\
**Post date:** [March 9, 2004, 11:26am UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/12 "2004-03-09T11:26:42Z")

</div>

> [@+MDI](#):
>
> John, the while loop will cease looping when the value returned by nexToken is NULL, I think.

You could be right, but when I learnt C my teachers would have considered that not to be very clear coding. (I’ve mostly forgotten C though)

---

<div class="post-metadata">

**Author:** ![Xerxes](https://avatars.discourse-cdn.com/v4/letter/x/d2c977/32.png) [@Xerxes](https://boards.straightdope.com/u/Xerxes)\
**Post date:** [March 9, 2004, 12:13pm UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/13 "2004-03-09T12:13:22Z")

</div>

double operand = 0.0;  
char _token;  
token = (char_) malloc(20);  
while (token = (char\*) nextToken(fp)) {…

The first problem is: is nextToken returning a (char \*) to a static buffer that it owns? (If so, you’ll want to strncopy to your newly malloc’d 20 byte buffer, but CHECK that malloc didn’t return null). Or is it malloc’ing on your behalf (in which case (a) your initial malloc is redundant, and you’ll forever lose the address the first time it’s overwritten by nextToken and (b) you’ll want to free it at the end of the loop.

```
  operand = strtod(token, &pp);

```

if (pp != token) {

There’s generally more than one way to skin a cat; Like the other responders, I don’t know why pp!=token is generating a segfault, but you should be able to check whether operand is a valid double by checking the length of pp (i.e. strlen(pp)); It’s guaranteed to contain a) any unrecognised/unparsed characters then b) the original strings terminating null (so strlen shouldn’t ride off into the sunset.

If all that doesn’t help, maybe try looking at sscanf, which returns the number of correctly parsed elements (the args are different to strtod, so you’ll have to look it up). Anyhow, hope some of this helps…

---

<div class="post-metadata">

**Author:** ![panamajack](https://avatars.discourse-cdn.com/v4/letter/p/47e85d/32.png) [@panamajack](https://boards.straightdope.com/u/panamajack)\
**Post date:** [March 9, 2004, 6:48pm UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/14 "2004-03-09T18:48:06Z")

</div>

**Jeff Lichtman** pointed out my error. I was just plain wrong. I honestly looked at what I wrote several times and still saw \*endp for the second part.

As for the seg fault, is it true that you can do equality/inequality with non-NULL pointers not in the same array? Perhaps this is the problem.

As recommended by others, I’d look for some other way to do it (try some of the functions in \<string\>, like strtok or strspn.)

---

<div class="post-metadata">

**Author:** ![sciguy](https://avatars.discourse-cdn.com/v4/letter/s/e68b1a/32.png) [@sciguy](https://boards.straightdope.com/u/sciguy)\
**Post date:** [March 9, 2004, 8:04pm UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/15 "2004-03-09T20:04:08Z")

</div>

[QUOTE=panamajack]  
As for the seg fault, is it true that you can do equality/inequality with non-NULL pointers not in the same array? Perhaps this is the problem.  
QUOTE]  
In C and C++ you can do whatever you within a test, and it will count as “true” if the code inside the test returns non-zero, and “false” if the code inside the test evaluates to zero. Other languages may be more strongly typed.

Assignment operators “return” the value being assigned to the variable. So in your case you have

```auto

token = (char*) nextToken(fp)

```

If nextToken(fp) returns anything that is non-zero, it evaluates as true. And since the zero value of a char\* is the same as “null”, the while loop will continue until the next token of fp is null.

Now this will be a problem if fp isn’t terminated properly, since the while loop will merrily traipse through memory until it finds a null.

Of course, using the assignment operator (’=’) inside a test is generally considered a bad style choice. People have a hard enough time remembering to use the double equals for comparisons (I’ve had single equals cause me quite a few problems with loops) without introducing situations where a single equals is the desired functionality.

---

<div class="post-metadata">

**Author:** ![DaveW](https://avatars.discourse-cdn.com/v4/letter/d/9d8465/32.png) [@DaveW](https://boards.straightdope.com/u/DaveW)\
**Post date:** [March 9, 2004, 8:40pm UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/16 "2004-03-09T20:40:02Z")

</div>

Without knowing what compiler is being used, and without seeing the input file, my guess would be that **Omphaloskeptic** has nailed this one. pp should be initialized to _token_, and not to 0. The way the code is now, if the token is PI or E, the “if (pp!=token)” branch will be taken, and whatever is in there is causing the segfault. Obviously, if you comment out that whole if-then block, the segfault will vanish, but so will your functionality.

On another note, you might want to let people use “pi” or “e” instead of only their upper-case equivalents, and for source code clarity test the return value explicitly. In other words, turn “if (!strcmp(token,“PI”))” into “if (str **i** cmp(token,“PI”) **!=0** )” Do it for the “E” test, as well.

---

<div class="post-metadata">

**Author:** ![panamajack](https://avatars.discourse-cdn.com/v4/letter/p/47e85d/32.png) [@panamajack](https://boards.straightdope.com/u/panamajack)\
**Post date:** [March 9, 2004, 8:50pm UTC](https://boards.straightdope.com/t/converting-a-char-to-a-double-in-c/233229/17 "2004-03-09T20:50:59Z")

</div>

Sorry, I was referring to the (pp != token) part (the apparent cause of the crash).

I know that \>, \<, etc. are undefined for pointers not in the same array, and I know that you can always compare to NULL, I just wasn’t sure about != or == (although now I think about it I’m pretty sure that you can). This would be easy to test with your compiler at any rate (possibly some optimization is converting != to another relational operator).

For this exact purpose it’s probably better to use something like memcmp, though I still think there’s better ways to do it.
