-1

I am writing two ASCII char arrays to an LCD screen perfectly fine. However I need an if-condition to compare these two values.

Originally I attempted to simply compare them like this:

if(currentTemp < triggTemp)
{
   alarmTriggered = true;
} 

As this didn't work, I am attempting to convert them to floats from their ASCII strings using atof().

However this doesn't seem to want to work either, am I missing something silly here? Necessary code below:

void main () {

    char triggTemp;
    int buttonBool = 0;
    bool alarmTriggered = false;
    char currentTemp;
    double f_triggTemp = 0;
    double f_currentTemp = 0;


  TRISC = 0x00;
  init();
  Init_lcd();



  while(1) 
  {
      //char bufferString[4];
      currentTemp = get_temp();

      f_currentTemp = atof(currentTemp);
      f_triggTemp = atof(triggTemp);

      if(f_currentTemp < f_triggTemp)
      {
          alarmTriggered = true;
      }



      if(alarmTriggered == true)
      {
          soundBuzzer();
      }
}

The values are being returned from functions in this form:

//some function
char bufferString[4];

sprintf(numberString, "%s.%s", itoa(bufferString,setTemp,10),
             itoa(bufferStringDec,setTempDec,10));

    return numberString;

In essence, I am trying to compare these char arrays of ASCII characters so I can use an if condition to trigger an alarm.

I tried to keep the code snippets short, I can clarify on request. Thanks for any help.

EDIT: I know I'm using atof into double variables; the prototype in my library is set up like that.

Nayuki
  • 17,911
  • 6
  • 53
  • 80
James
  • 356
  • 2
  • 13

3 Answers3

0

I think this is what you are doing:

char* some_function() {
  char temporary_string_buffer[32]; // Or some other fixed size
  snprintf(temporary_string_buffer, 32, "some format");
  return temporary_string_buffer;
}

You can't do that. OK, you can do that -- you probably just did -- but it has Undefined Behaviour, because the lifetime of temporary_string_buffer ends with the return statement. In the caller, the function will be returning what's colloquially known as a "dangling pointer"; in other words, a pointer whose target no longer has any meaning. So by the time you get around to calling atof on that value, it may have been used for something completely different.

If you want to return a string to the caller, either:

  • Dynamically allocate the string with malloc and make sure the caller knows that they need to free it; or

  • Get the caller to give you the address of a buffer and its length (as arguments), and fill in the supplied buffer. You can use the return code for a success indicator, or (like sprintf) as a count of bytes, or whatever.

rici
  • 234,347
  • 28
  • 237
  • 341
  • I understand what you mean, but slightly confused as to why in this case I am allowed to print the ASCII string to my LCD like this using the returned chars. Surely if the life of the buffer ends with the return statement, I shouldn't be able to print an accurate LCD value? – James Jan 14 '16 at 19:47
  • @James: Undefined behaviour is *undefined*. Maybe it does one thing, maybe it does another. The fact that by coincidence it does something which you interpret as being accurate does not imply that the next time you make the same mistake, you won't get a segfault or worse. In other words, with C you are supposed to know what you can't do. If you do it anyway, the C compiler is under no obligation to tell you that you shouldn't do that. Undefined behaviour is not an error message. It's just plain undefined. – rici Jan 14 '16 at 19:52
  • I'm understanding that to mean that in this case, the pointer isn't being used for anything different, but that's by chance. The value could have been overwritten at any point. I'm looking into correcting this mistake using your advice. Any further clarification on the first option? never used malloc or that sort of method – James Jan 14 '16 at 19:57
  • @james: the second method is probably more common anyway. – rici Jan 14 '16 at 20:01
  • I'm somewhat confused now, I thought by returning a value from a function it simply just gave me a variable. Shown here: currentTemp = get_temp(); I was under the impression from my coding experience that the currentTemp variable now held the value returned from the function? – James Jan 14 '16 at 20:10
  • @James: it does. And if your function returns a pointer, then that is what is returned. But a pointer is not what is pointed to. Suppose someone builds a house, writes the address on an envelope, and hands you the envelope. Now you have the house's address. But what good will that do you when they abandon the house and someone else moves in? The pointer to the house can be passed from hand to hand, but the house itself is not. – rici Jan 14 '16 at 22:08
  • Im afraid I was very tired when reading your first answer. I've just noticed upon re-reading that you assume I'm returning a pointer with char* someFunction(); In actual fact its just: char someFunction(); Which is why i was a tad confused when dangling pointers were brought into it when i thought I was returning literal values. – James Jan 17 '16 at 19:28
  • @james: returning a `char` is fine, but is that really what you want to do? A `char` is a single character, not a string. You cannot use it as though it were a string. It's an integer type whose value is the ascii code of the character. – rici Jan 17 '16 at 19:47
0

char currentTemp; ... atof(currentTemp); will not work. double atof(const char *nptr) expects a pointer to a string, not a char.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Create a function to do the compare for you. Here is a complete test program. You just compare the array element one by one.

int is_greater(char a[], char b[], int z, int z1) {
    int i = 0;
    for( i = 0; i < z; i++ ) {
        if( a[i] > b[i] ) return 1;
    }
    return 0;
}
Michael
  • 401
  • 5
  • 16
  • You either need to pass the length of both or if you know they are the same length, you can do as I have here. – Michael Jan 14 '16 at 19:56
  • I'm not trying to compare the length of the two char arrays. I'm trying to compare the numerical values of the numbers represented by each array. One array holds a float with 1 decimal place, the other holds to 5. – James Jan 14 '16 at 20:00
  • Sorry. I misunderstood what you were trying to do. The solution is nearly the same. If you compare each character in the array, any charachter that is greater indicates the number is greater. – Michael Jan 14 '16 at 20:07
  • This is indeed a function I will probably end up using a manifestation of (so thanks!), but the real problem that has some to light is the fact I am using dangling pointers to variables that could well have been overwritten in memory. I was under the impression that by returning a value from a function, I could use that variable. But this doesn't seem to be the case – James Jan 14 '16 at 20:09