data to buffer

Hi, i have a question about a code i wrote:

//print data to buffer

#define buf1Max 256
char buf1[buf1Max];
char data[30];

int bufIndex = 0;

void dataToBuffer(){
    for (int x = 0; x < strlen(data); x++){ //data to buffer
      if (bufIndex < buf1Max){
        Serial.println(bufIndex);
        buf1 [bufIndex] = (data[x]);
        bufIndex++;
      }//end if bufIndex
  }//end for dataToBuffer
  
} //end void dataToBuffer

void setup() {
  
  Serial.begin(9600);

  sprintf(data,"%d",12000); 

  for (int x = 0; x < 200; x++){ //save data to buffer, more than buffer1 length.
    dataToBuffer();
  }
  
  Serial.println(buf1);
  Serial.println(strlen(buf1));



}

void loop() {
  // put your main code here, to run repeatedly:

}

I created a buffer with 256 chars (buf1[0 to 255] and since i typed “bufIndex < buf1Max” i would expect its gonna to fill the buffer from 0 to 255. But… it the serial outputs this (I deleted first 251 values):

252
253
254
255
120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000112000
261

I got 261 chars, but i told the array is max 256 chars long… Why is the array now 261 chars long, why are the last values are a mess and where the # are the chars from 255 to 261 stored?

When i change “char buf1[buf1Max]” to “char buf1[buf1Max+1]” it seems to work; i got 256 chars stored. but why do i need to make the char array one char larger? i dont want to make the buf longer then 255chars and fill it completely up with values…

Its not really about the solution…, but about what i dont understand well.

When printing a char array, the print function expects it to be null terminated. It is expecting a null terminated string. So it will print until it hits the first 0. The called function has no idea how long the buffer is, it's just going to print until it hits a 0.

If you want to print the contents of that array then use a for loop to print them one at a time.

Here is a good resource about null-terminated strings.

That is a dangerous way of writing code, you should avoid to write code like that. Try to solve the problem in a different way.

This is what you do:

index = 0;
for ( int i = 0; i < 200; i++) 
{
  for ( int j = 0; j < 5; j++)
  {
    if ( index < 256)
    {
      buffer[index] = data[x];
      index++;
    }
  }
}

The buffer is written until the very last character. That means there is no zero-terminator. The value of “261” is not an index, that is the strlen. You can easily see that, when you change it into:

  Serial.print( "buf1 = ");
  Serial.println( buf1);
  Serial.print( "strlen(buf1) = ");
  Serial.println( strlen(buf1));

The result is:

252
253
254
255
buf1 = 120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000120001200012000112000
strlen(buf1) = 261

If i understand correctly, never try to fill up a char array completely, and use the /0? I was thinking about this:

char buf1[bufMax];
int data =0;

sprintf(buf1, "%s%d,", buf1, data);

in this case, will the already written buf1 data re-written? Is this method fast and reliable?

Jansun84: If i understand correctly, never try to fill up a char array completely, and use the /0? I was thinking about this:

char buf1[bufMax];
int data =0;

sprintf(buf1, "%s%d,", buf1, data);




in this case, will the already written buf1 data re-written? Is this method fast and reliable?

Not fast and bloats code. Why not just strcat it on there?

it combines strings? I need to add a int to a string.

first put it in a separate char array and then combine arrays? or..?

Jansun84: or..?

itoa

hmm.

Does itoa always start filling the array at index 0, or can i also point to another index?

Jansun84: hmm.

Does itoa always start filling the array at index 0, or can i also point to another index?

Use pointer math. The name of an array is just a pointer to the first element.

char buff[30] = {};

*buff = 'a';   // puts an a in slot 0

*(buff + 3) == 'b';   // puts a b in slot 3

int anInt = 5;

itoa (anInt, buff + 5, DEC);  // puts a '5' in slot 5.

Thanks, helps. I saw itoa gives a return value, a pointer to “/0”. So i tried to make it thing visible:

  sprintf(buff,"%s","11111111111111111111111111");
  
  *buff = 'a';   // puts an a in slot 0
  *(buff + 2) = 'b';   // puts an b in slot 3

  startIx = buff;

  Serial.print("Start index position: ");
  Serial.println(startIx);
  
  retVal = itoa (anInt, buff + 15, DEC);  // puts a '5' in slot 5.

  Serial.print("in Array stored: ");
  for(int x = 0; x < 30;x++){
    Serial.write(buff[x]);
  }
  Serial.println("");
  Serial.print("New index position: ");
  Serial.println(retVal-startIx);

but… it return the “\o” before the new value is added. I can easily find the new end with strlen ofcourse, but why does it return a value what you already know since you have to fill it in in the itoa statement?

So this is what i got:

  itoa (anInt, buff + strlen(buff), DEC);

code before:

sprintf(buff, "%s%d,", buff, anInt);

I cant see why, but the new one should be a better way?

Well, if Delta_G claims that it is not fast and bloats code, then he might have to prove how much slower it is :grin:

The sprintf() function is not small, but it processes the formatted string pretty fast.

I don't know that it is that much slower. But you can simply compile the code and see if it is larger. That's not hard.

Or keep the sprintf version. It was just a suggestion. It's not like you have to write code to my specification or anything.

i would like to know if my Sprintf version not the completely rewrites into the buffer. when i say:

sprintf(buff, "%s%d,", buff, anInt);

Does it overwrite buff[0],buff[1], etc with the same values, because %s is the same as the buffer? or is it that smart and only rewrites %d?

sprintf() has some input arguments, and a pointer to where to write to. It does not care what is already in the memory location to be overwritten. You could use

sprintf(&buff[strlen(buff)], "%d", anInt);

to NOT overwrite the first n characters of buff. But there is little advantage in doing that.

If you were going to do that it would make more sense to grab a pointer to the end of the string and use itoa.

Thanks. Im new to pointers, this is a big help, tabks.

I need to seperate values with "," or " ". So i think i can best use sprintf then, like paul suggest with pointer to the "/0" position.