using sprintf function in arduino

So I am inserting to database using mysql connector,

I have been using but I was suggested to use char buffer, and sprintf() to populate it will not fragment memory the way that Strings can.

so I took a look in mysql arduino example sketch and it uses this:

const char INSERT_DATA[] = "INSERT INTO test_arduino.temps VALUES (%s, NULL)";

INSERT_DATA i.e the query storing variable is declared char of indefinite length !

and later used sprintf

char query[64];
char temperature[10];
dtostrf(value_read, 1, 1, temperature); 
sprintf(query, INSERT_DATA, temperature);

looking at the insert query it has %s so does that mean in the call to function sprintf the value of temperature is inserted to INSERT_DATA and then it is fed to the query variable which is the first in call to sprintf ?

thats what I don't get ? I am not cpp programmer I have been programming with python and still thinking like a python programmer , so any help would be greatly appreciated

so does that mean in the call to function sprintf the value of temperature is inserted to INSERT_DATA

Not exactly.

In that example, INSERT_DATA is the format statement. The format statement contains one format specifier, so one additional argument is needed (for a total of three). The format specifier is an s, so the third argument needs to be a string.

temperature is a string, so it is appropriate as the third argument.

What happens, then, is that literal parts of the format statement are copied to the output buffer, until a forma specifier is encountered. That means that "INSERT INTO test_arduino.temps VALUES (" will be copied to query.

Then, the appropriate value is substituted in place of the format specifier - the string temperature is added to the end of query.

Finally, the remaining literal characters, ", NULL)", in the format statement are added to the end of query.

aha, that means It would be much convenient to use sprintf then using String and concatenating then with values from other sensors ...

phewww.

but of temperature to be a string I would have to convert any string or float to a string ? you meant char datatype ?

but of temperature to be a string I would have to convert any string or float to a string ? you meant char datatype ?

There is a format specifier for floats (%f), but the Arduino team disabled support for that format specifier. (It can be re-enabled, relatively simply.) So, yes, you need to convert any float to a string using some other means.

You do not need to convert strings to strings. Yes, a string is a NULL terminated array of chars.

thank you , what do you mean by “NULL terminated array of chars.” ?

seaurchin: thank you , what do you mean by "NULL terminated array of chars." ?

I mean that you really, REALLY, need to buy a C programming book, and spend some time reading.

char str = {‘s’,‘t’,‘r’,’\0’};

‘\0’ is the null terminator. It is used by the string library to know where the end of the string is.

PaulS: I mean that you really, REALLY, need to buy a C programming book, and spend some time reading.

yes thats a thing I am going to do first. I am just restricted by lack of time and living alone doing every thing by myself. Its just that in my list of priorities I have a huge pile.

Hi,

Until you get around to buying that book (Kernighan & Ritchie is highly recommended), this may be useful: www.cplusplus.com/doc/tutorial/ntcs/ --Michael

I leanred from office colleague I can use stringStreams !

#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>

using namespace std;

int main()
{
    float outdoorTempInC = 15;
    int outoorHumidity = 23;
    float indorTempinC = 20;
    int humidity = 22;
    int val = 400; // soil sensor reading
    int avgVal = 38; // avaerage of 10 values of soils sensor
    char statusMsg[50] = {"Hello World"} ;
    std::stringstream sqlQuery;
    
    sqlQuery  << "INSERT INTO arduinoSensorData.sensorLog (out_temperature,  " 
        << "out_humidity,  drwngRoom_temperature, drwngRoom_humidity, "
        << "pot1_soilMoisture, pot1_avg_SoilMoisture, wateringPot1) VALUES ('" 
        << outdoorTempInC << "', '" << outoorHumidity << "', '" << indorTempinC
        << "', '" << humidity << "', '" << val << "', '" << avgVal << "', '"
        << statusMsg << "');";

    cout << sqlQuery << "\n";
    char *mychar = new char[sqlQuery.str().length() + 1];
    strcpy(mychar, sqlQuery.str().c_str());
    cout << mychar << "\n";
    return  0;
}

now my only query is : is it performacne intuitive when used in arduino ?

Your code example looks like it was compiled under Visual Studio and that's not going to work too well with the Arduino. First, the statement:

const char INSERT_DATA[] = "INSERT INTO test_arduino.temps VALUES (%s, NULL)";

the const keyword means you cannot change the content of that string at runtime. I doubt that's what you really want. In the example below, if newData[] is what you want to INSERT into the db, this shell test program might help you see how to build the string:

void setup() {

  Serial.begin(9600);
  Serial.println("Enter input data (20 chars max):");

}

void loop() {

  char insertData[100] = "INSERT INTO test_arduino.temps VALUES ('";
  char kbInput[21];
  int charsRead;

  if (Serial.available() > 0) {     // Something's in the Serial buffer...
    charsRead = Serial.readBytesUntil('\n', kbInput, sizeof(kbInput) - 1); // Leave room for NULL
    kbInput[charsRead] = NULL;      // Now it's a C string
    strcat(insertData, kbInput);
    strcat(insertData, "' NULL)");
    Serial.println("SQL string: ");
    Serial.println(insertData);
    Serial.println("\nEnter input data (20 chars max):");
  }
}

Obviously, you'll need to modify it, but it gives you a way to build the query string without using sprintf(), which uses more memory than needed. Make sure you have the input termination textbox set to Newline.

econjack:
Your code example looks like it was compiled under Visual Studio and that’s not going to work too well with the Arduino.

I believe you didnt had a look at my previous reply .
I think I can use StringStream i.e.:

#include <sstream>

however I discovered it is not present in Arduino :confused:

I am quite puzzled :

/Users/seaurchin/Library/Arduino15/packages/arduino/hardware/avr/1.6.16/cores/arduino
already has a header file saying Stream.h ?

is it the same sstream I used at office or different one ?

I googled web and found this: arduino/libs/avr-stl/include at master · ddierickx/arduino · GitHub

how can I install it along with other exiting libraries ? I am on Mac OS Sierra.

I think I can use StringStream

Why do you think that?

is it the same sstream I used at office or different one ?

Why would you think that stringstream would be defined in Stream.h? Did you even bother looking in Stream.h?