2

So I'm writing a program for a school project, and part of it requires having a user put in a random number at the command line. The program then uses atof to convert the number to a float so I can do some math with it. That part of the program looks like:

#include <iostream>
#include <cstdlib>
#include "bmplib.h" //this is just something the prof. gave us to help read the image
#include <cmath> //i might use this later in the program

#define nummethods 2
using namespace std;

unsigned char input[256][256][3];
unsigned char bg [256][256][3];
unsigned char output[256][256][3];
unsigned char m[2][256][256];

int main(int argc, char *argv[])
{

  int h,i,j,k;
  double x,y,z;

  //code to read img here and make sure user puts correct number of arguments in 
 //command line

  for (i=0;i<256;i++){
    for(k=0;k<3;k++){
      y = y + input[i][0][k];
    }
  }

 cout >> y >> endl; //this is giving me 36,164,75 which in RGB is green       

 x = atof(argv[3]); //the number was the 3rd thing typed in at the command line
 cout << x << endl;

 z = x + y; //this isn't the exact program, but you get the idea
 cout << z << endl;

//there's some more code after this written by the prof. that manipulates the image,
//but i don't think its relevant since it does not use the argv[3] value
}

The program compiled but it didn't work right. I tested it by adding a cout << x; and it showed that atof was giving me the wrong number. For example, when put 5.0 as my number into the command line, it showed that my x was 379.7465. Any idea what's wrong?

Dee
  • 21
  • 1
  • 2
  • 4
  • 2
    Can you reduce it to a minimal case? For example, do `atof(argv[1])` and try it with `./program 5.0` and see what you get – Foo Bah Oct 10 '11 at 03:38
  • did you put the header file for atof? Testcase would be helpful – eran Oct 10 '11 at 03:40
  • 3
    Also try `cout << argv[3]`. It might not be want you're expecting. – stardt Oct 10 '11 at 03:42
  • How are you printing the results? Sounds like your printf format is incorrect. – Graham Perks Oct 10 '11 at 03:47
  • @Dee - welcome to Stack Overflow! Please post a short example of actual, compilable code that demonstrates the problem. You may actually answer your own question by doing so :) – Brian Roach Oct 10 '11 at 03:48
  • 2
    Chances are that atof _is_ working but _you_ doing something wrong. Don't go blaming standard libraries (or even non-standard ones) without having a very solid example, and then I'd still phrase my question as "What am I doing wrong with libBLAH?" rather than "libBLAH is broken". – Michael Anderson Oct 10 '11 at 03:56
  • 2
    To expand on Michael's comment which is spot on: [First rule of programming: It's always your fault](http://www.codinghorror.com/blog/2008/03/the-first-rule-of-programming-its-always-your-fault.html) – Brian Roach Oct 10 '11 at 03:59
  • Well I edited the code so it the example actually compiles. I realize it's probably something I did, but I can't post the /exact/ code since this is a school project. If it helps, the part before this just reads a .bmp picture the user specified at the command line, stores the RGB values into an array, and then computes the average RGB values across a column. I know that part works fine because I've tested it by cout >> avgRGBvalue; and it gives me what I want. – Dee Oct 10 '11 at 04:07
  • 1
    Are you sure you're indexing the arguments correctly? Don't forget that `argv[0]` contains the name of the program. – Adam Rosenfield Oct 10 '11 at 04:08
  • @Dee - add a cout for argv[3]. I think you'll find that it *isn't* 5.0 – Brian Roach Oct 10 '11 at 04:11
  • please post the exact command line you're using – stardt Oct 10 '11 at 04:15
  • Added a cout for argv[3]. It gave me a 5. :V And yes, i'm indexing it properly. The command line goes program_name img1.bmp img2.bmp number new_img.bmp new_img.bmp Anyway I appreciate you guys taking the time to help! I'll try to find a way to most a more complete version of the code...I just don't want my teacher to think I'm cheating by having StackOverflow look at the code. :| – Dee Oct 10 '11 at 04:18
  • Added everything that happens before I try to change the argv[3] value. – Dee Oct 10 '11 at 04:46
  • 1
    If you've truly shown everything, then your double loop is producing zero in a complex way. But you said it produces 'green', so you've not shown everything. If you get rid of all the globals and the code messing with them, do you still run into the problem? If so, then you have one set of issues to look at; if not, then you may have some sort of buffer overflow in the code you've deleted but not shown us. It very often works out that if you get mysterious results, the trouble is not in the code that is shown but in the code that is not shown. – Jonathan Leffler Oct 10 '11 at 05:09
  • @Jonathan I tried your suggestion. You're right, it's a problem with some other part of the code. Thanks for the help though! :) This is going to be a long night... – Dee Oct 10 '11 at 05:42

2 Answers2

10

Are you including stdlib.h ??

I find if i dont explicitly import stdlib.h the code complies and runs, but atof returns 0, when i include stdlib.h it returns the value as expected.

Im using the gcc for c code. I assume its the same for c++.

Stephen
  • 4,228
  • 4
  • 29
  • 40
  • 4
    This could be a possible cause of a similar problem in C, but in C++, function prototypes are required. A failure to include `stdlib.h` would cause a compiler error when trying to use `atof` in C++. – Adam Rosenfield Oct 10 '11 at 04:07
  • I'm curious as to _why_ we get 0 instead of a compile (linker) error like we do if we use a completely fabricated function rather than atof. – Phil Jan 05 '21 at 01:40
2

Even though its name suggests it returns a float, atof actually returns a double.

So, you'll have to cast it to a double in order for it to become a float.

Here's an example:

float value = (float)atof(argv[1]);
printf("%.2f + 3 = %.2f", value, (value + 3));

And this works perfectly.

Jack Greenhill
  • 10,240
  • 12
  • 38
  • 70
  • While you're probably correct on the root cause, casting a `double` to `float` is not guaranteed safe for precision. The answer is to use a `double` – Brian Roach Oct 10 '11 at 03:58
  • @BrianRoach: I don't believe the closest representation of double 5.0 is 379.7465 float. – Daniel Oct 10 '11 at 04:05
  • @Dani - heh, there is that. Fingers going faster than brain, I should probably get some sleep. However, the casting from double to float part still stands. (And the real problem is in code that the OP isn't posting) – Brian Roach Oct 10 '11 at 04:09