Unexpected behavior of char[] in print / println

Hey. While working with an array of characters I checked the value of the array members by using the print / println function. The code boils down to :

void setup() {
char[] ch = new char[2];
ch[0] = ‘0’;
ch[1] = ‘0’;
print("two statements: ");
println(ch[0] + ch[1]);
println("one statement: " + ch[0] + ch[1]);
exit();
}

which on the console delivers:

two statements: 96
one statement: 00

I am able to indicate the origine of the 96 as being twice de ASCII code of ‘0’ (zero) but the difference in behaviour remains strange. Although I can live with the phenomenon, to me it seems reasonable two have the print function work in both case in the same way.
Thur

Hi,

Welcome to the forum! :wink:

Note that you can format your code by using the </> button when editing a message.

The fact you are seeing 96 is because the way Java handle conversion when using an operator :

If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

  • Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

  • If either operand is of type double , the other is converted to double .

  • Otherwise, if either operand is of type float , the other is converted to float .

  • Otherwise, if either operand is of type long , the other is converted to long .

  • Otherwise, both operands are converted to type int .

So when adding two char, they are converted to int so their UTF-16 code :

char ch1 = '0';
char ch2 = '0';

println(ch1 + ch2);

// -> 48 + 48 = 96

Now in the second print statement, you have associativity. For example the associativity of the + operator is left to right.

It means that it first performs left operations and propagate to the right members of the expression so :

"one statement: " + ch[0] + ch[1] = ( ( "one statement: " + ch[0] ) + ch[1] )

But in that case, adding a string with an int gives you a string so you have :

( ( "one statement: " + ch[0] ) + ch[1] )

( "one statement: 0" + ch[1] )

"one statement: 00"

So this has nothing to do with the fact that the char are taken from an array.

Hope it helps :slight_smile:

1 Like

Try using a comma instead of the addition sign. The addition sign will add numbers when paired with other numbers, but will convert a number to a string if paired with a string, at least that’s my understanding.

void setup() {
char[] ch = new char[2];
ch[0] = '0';
ch[1] = '0';
print("two statements: ");
println(ch[0] + ch[1]);
println("one statement: ", ch[0] + ch[1]);
exit();
}

2 Likes

paulgoux

hi
if you kind explain this for me

String msg = "<0,0>";



void drawSliderOne() {
  pushStyle();
  noStroke();
  num_1 = map(loc_1, 0.0, width, 2, 10);



void drawSliderTwo() {
  pushStyle();
  noStroke();
  num_2 = map(loc_2, 0.0, width, 2, 10);

void sendData() throws IOException {
  msg = "<"+int(num_1)+","+int(num_2)+">";
String msg =   "<0,0>"//   the start and end delimiter  < > what to add here  "<0,0>"  to send more 

and what to add here ??

String msg = "<0,0>";



void drawSlider1() {
  pushStyle();
  noStroke();
  num_1 = map(loc_1, 0.0, width, 2, 10);



void drawSlider2() {
  pushStyle();
  noStroke();
  num_2 = map(loc_2, 0.0, width, 2, 10);
 
void drawSlider3() {
  pushStyle();
  noStroke();
  num_3 = map(loc_3, 0.0, width, 2, 10);
 
void drawSlider4() {
  pushStyle();
  noStroke();
  num_4 = map(loc_4, 0.0, width, 2, 10);
 
void drawSlider5() {
  pushStyle();
  noStroke();
  num_5 = map(loc_5, 0.0, width, 2, 10);
 
void drawSlider6() {
  pushStyle();
  noStroke();
  num_6 = map(loc_6, 0.0, width, 2, 10);
 


void sendData() throws IOException {
  msg = "<"+int(num_1)+","+int(num_2)+">"; //how to add num_2 to num_6 here ?

what to add here

String msg = “<0,0>”;

and what add here

msg = “<”+int(num_1)+","+int(num_2)+">"; //how to add num_2 to num_6 here ?

thank you

The comma can only be used in println or print, its a parameter separator, not a string separator.

//invalid
String s ="4","4";
//valid
String s ="4"+"4";

Although I would probably refrain from arithmetic in strings as I don’t fully understand how the numbers will come out. So perhaps keep arithmetic in its native integer or float the convert your answer to string. But that’s up to you.

2 Likes

The comma here is delimiter

String msg =   "<0,0>"
void sendData() throws IOException {
  msg = "<"+int(num_1)+","+int(num_2)+">";

could be

String msg =   "<0#0>"

void sendData() throws IOException {
  msg = "<"+int(num_1)+"#"+int(num_2)+">";

josephh
can you help ?

if you kind

Hi,

Can you please post some code that works? I suppose you are using Processing Java but there’s missing brackets and semicolons.

Also can you describe more precisely what is the goal of your program? (Because it’s difficult to understand with two sentences…) :wink:

2 Likes

josephh

this is working code

what i need is >> if i want to increase the slider from 2 to six what should i add here

}

void sendData() throws IOException {
msg = “<”+int(num_1)+","+int(num_2)+">"; in this line how to add from int(num_3) to int(num_6)
mmOutputStream.write(msg.getBytes());
}

this adding just what i want to code

int(num_3)
int(num_4)
int(num_5)
int(num_6)


import android.Manifest; 
import android.content.pm.PackageManager; 
import android.os.Build; 
import android.os.Build.VERSION_CODES; 
import processing.core.PConstants;
import android.app.Activity; 
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;
OutputStream mmOutputStream;
InputStream mmInputStream;
Activity activity;
Permission bp, afl;

Thread runThread;
byte[] readBuffer;
int buffer_index;
int counter;
boolean stop_thread, plotting = false, init = true;
boolean drag_just_finished;

String msg = "<0,0>";
String device_name = "HC-05";
String r_str, t_str;
boolean permissions_granted;
float a, b;
float px_1, py_1, x_1, y_1, px_2, py_2, x_2, y_2;
float loc_1, loc_2, num_1 = 0, num_2 = 0;
String[] y_values = {"0#0"};

void setup() {
  fullScreen();
  orientation(LANDSCAPE);
  bp = new Permission(this, "BLUETOOTH");
  afl = new Permission(this, "ACCESS_FINE_LOCATION");
  textAlign(CENTER);
  textSize(70);
  t_str = "Click to connect.";
  textSize(12); // To create a "text width factor",
  float twf = width/textWidth(t_str);
  int f = 4; // Empericaly found 
  textSize(f*twf); // Making it  proportional for other screen resolutions
  loc_1 = width/50;
  loc_2 = width/50;
}

void draw() {
  if (plotting  == false && init) {
    background(150);
    text(t_str, width/2, height/2);
    strokeWeight(10);
    noFill();
    stroke(50);
    rect(0, 0, width, height);
  } else if (plotting  == false) {
    drawSliderOne();
    drawSliderTwo();
  }
}

void mousePressed () {
  if (init) {
    try {
      init = false;
      findBluetooth();
      connect();
      plotting = true;
      fill(0, 0, 90);
      rect(0, 0, width, height); 
      drawSliderOne();
      drawSliderTwo();
    } 
    catch (IOException ex) {
      println(ex);
    }
  }
}

void mouseDragged() {
  plotting = false;
  if (mouseY > height-height/8) {
    loc_1 = mouseX;
    if (loc_1 < width/50) loc_1 = width/50;
    if (loc_1 > width-width/50) loc_1 = width-width/50;
    try {
      sendData();
    }  
    catch (IOException ex) {
    }
  } 
  if (mouseY > height-height/3 && mouseY < height-height/3+height/8) {
    loc_2 = mouseX;
    if (loc_2 < width/50) loc_2 = width/50;
    if (loc_2 > width-width/50) loc_2 = width-width/50;
    try {
      sendData();
    }  
    catch (IOException ex) {
    }
  }
}

void mouseReleased() {
  plotting = true;
}

void drawSliderOne() {
  pushStyle();
  noStroke();
  num_1 = map(loc_1, 0.0, width, 2, 10);
  fill(100, 180, 200);
  rect(0, height-height/8, width, height/8); 
  fill(200, 200, 255);
  rect(width/50, height-height/16, width-width/25, height/100); 
  fill(100, 100, 255);
  ellipse(loc_1, height-height/17, height/20, height/20);
  popStyle();
} 

void drawSliderTwo() {
  pushStyle();
  noStroke();
  num_2 = map(loc_2, 0.0, width, 2, 10);
  fill(100, 180, 200);
  rect(0, height-height/3, width, height/8); 
  fill(200, 200, 255);
  rect(width/50, height-9*height/32, width-width/25, height/100); 
  fill(100, 100, 255);
  ellipse(loc_2, height-9*height/32, height/20, height/20);
  popStyle();
}    

void plot(String r_str) {
  if (r_str.length() < 3 || r_str == null) r_str =  "0#0";
  if (plotting) {
    y_values = split(r_str, "#");
    stroke(0, 200, 255);
    strokeWeight(2);
    y_1 = int(y_values[0])+height/6;
    line(px_1, py_1, x_1, y_1);
    py_1 = y_1;
    px_1 = x_1;
    x_1++;
    if (x_1 > width) {
      x_1 = y_1 = px_1 = py_1 = x_2 = y_2 = px_2 = py_2 = 0;
      fill(0, 0, 90);
      rect(0, 0, width, height-height/3);
    }
    y_2 = int(y_values[1])+height/2;
    line(px_2, py_2, x_2, y_2);
    py_2 = y_2;
    px_2 = x_2;
    x_2++;
  }
}

void sendData() throws IOException {
  msg = "<"+int(num_1)+","+int(num_2)+">";
  mmOutputStream.write(msg.getBytes());
}


void findBluetooth() {
  mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  if (mBluetoothAdapter == null) {
    println("No bluetooth adapter available");
  }
  if (!mBluetoothAdapter.isEnabled()) {
    Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    activity.startActivityForResult(enableBluetooth, 0);
  }
  Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
  if (pairedDevices.size() > 0) {
    print("Paired devices MAC Adress:");
    printArray(pairedDevices);
    for (BluetoothDevice device : pairedDevices) {
      print("Paired devices by name:");
      println(device.getName());
      if (device.getName().equals(device_name)) {
        mmDevice = device;
        println("Bluetooth device name found");
        break;
      }
    }
  }
}

void connect() throws IOException {
  UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //Standard SerialPortService ID
  mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);        
  mmSocket.connect();
  mmOutputStream = mmSocket.getOutputStream();
  mmInputStream = mmSocket.getInputStream();
  println("Bluetooth connected");
  //final Handler handler = new Handler(); 
  final byte delimiter = 33; //This is the ASCII code for a ! character
  stop_thread = false;
  buffer_index = 0;
  readBuffer = new byte[1024];
  runThread = new Thread(new Runnable() {
    public void run() {                
      while (!Thread.currentThread().isInterrupted() && !stop_thread) {
        try {
          int bytesAvailable = mmInputStream.available();                        
          if (bytesAvailable > 0) {
            byte[] packetBytes = new byte[bytesAvailable];
            mmInputStream.read(packetBytes);
            for (int i = 0; i < bytesAvailable; i++) {
              byte b = packetBytes[i];
              if (b == delimiter) {
                byte[] encodedBytes = new byte[buffer_index];
                System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                final String data = new String(encodedBytes, "US-ASCII");
                plot(data);
                buffer_index = 0;
              } else {
                readBuffer[buffer_index++] = b;
              }
            }
          }
        } 
        catch (IOException ex) 
        {
          stop_thread = true;
        }
      }
    }
  }
  );
  runThread.start();
}

void closeBluetooth() throws IOException {
  stop_thread = true;
  mmOutputStream.close();
  mmInputStream.close();
  mmSocket.close();
  println("Bluetooth stopped");
}

class Permission {
  PApplet parent;
  boolean requestedPortraitImage = false;

  Permission(PApplet pParent, String permissionName) {
    parent = pParent;
    parent.requestPermission("android.permission."+permissionName, "onPermissionResult", this);
  }

  void onPermissionResult(boolean granted) {
    if (granted)  println("User did grant permission.");
    else println("User did NOT grant permission.");
  }
}

void onPause() {
  try {
    closeBluetooth();
  } 
  catch (Exception ex) {
  }
  super.onPause();
}

void onStop () {
  try {
    closeBluetooth();
  } 
  catch (Exception ex) {
  }
  super.onStop();
}

void onRestart() {
  try {
    findBluetooth();
    connect();
  } 
  catch (IOException ex) {
    println(ex);
  }
}

and very thanks for you

and this is the arduino side

#include <SoftwareSerial.h>
#include <Wire.h>

SoftwareSerial mySerial(11, 12); // RX, TX

unsigned long previous_millis;
boolean new_data = false;
float a = 0, b = 0;
float i_1 = 0, i_2 = 0;
int udi_1 = 20, udi_2 = 1;
int y_1 = 0, y_2 = 0;
const byte number_of_chars = 32;
char receivedChars[number_of_chars];

void setup() {
  mySerial.begin(115200); // Set the baudrate equal to HC06 setting
  Serial.begin(9600);
}

void loop() {
  receivePacket();
  if (new_data == true) {
    parseData();
    new_data = false;
  }
   while (mySerial.available() <= 0) { 
    y_1 = int(70 * sin(a));
    a += i_1;
    if (a > TWO_PI) a = 0;
    mySerial.print(String(y_1) + '!');

    y_2 = int(70 * sin(b));
    b += i_2;
    if (b > TWO_PI) b = 0;
    mySerial.print(String(y_2) + '#');
  }
}


void receivePacket() {
  static boolean receiving = false;
  static byte index = 0;
  char start_mark = '<';
  char end_mark = '>';
  char rc;
  while (mySerial.available() > 0 && new_data == false) {
    rc = mySerial.read();
    if (receiving == true) {
      if (rc != end_mark) {
        receivedChars[index] = rc;
        index++;
        if (index >= number_of_chars) {
          index = number_of_chars - 1;
        }
      } else {
        receivedChars[index] = '\0';
        receiving = false;
        index = 0;
        new_data = true;
      }
    } else if (rc == start_mark) {
      receiving = true;
    }
  }
}

void parseData() {
  char * split;
  split = strtok(receivedChars, ",");
  udi_1 = atoi(split);
  split = strtok(NULL, ",");
  udi_2 = atoi(split);
  i_1 = udi_1/100.0;
  i_2 = udi_2/100.0;
  Serial.println(i_1);
  Serial.println(i_2);
}

Hi again,

When I said “working code”, I meant a simple example code that can be executed not your whole program.

I’m sorry but this is not clear at all :wink:

Do you want to have this ??

"<" + int(num_1) + "," + int(num_2) + "," + int(num_3) + "," + int(num_4) + "," + int(num_5) + "," + int(num_6) + ">" 
1 Like

its not the whole program. its the transmission just :smiley: :smiley:

yes this is what i want and i test it befor you send just now

"<" + int(num_1) + "," + int(num_2) + "," + int(num_3) + "," + int(num_4) + "," + int(num_5) + "," + int(num_6) + ">"

and i add t this

String msg = "<0,0,0,0,0,0>";

and in arduino

void parseData() {
  char * split;
  split = strtok(receivedChars, ",");
  int_1 = atoi(split);
  split = strtok(NULL, ",");
  int_2 = atoi(split);
  split = strtok(NULL, ",");
  int_3 = atoi(split);
 split = strtok(NULL, ",");
 int_4 = atoi(split);
  split = strtok(NULL, ",");
  int_5 = atoi(split);
  split = strtok(NULL, ",");
  int_6= atoi(split);

thanks for you

1 Like

and harder if you saw the whole Package

:heart: :innocent: :heart:

thanks for response

1 Like

josephh

hi

i did it

void sendData() throws IOException {

  
  
  


 
 
  msg2="<"+ int(val1)+","+int(val2)+","+int(val3)+","+int(val4)+","+int(val5)+int(val6)+">";

 mmOutputStream.write(msg2.getBytes());
}

arduino

void parseData() {
  char * split;
  split = strtok(receivedChars, ",");
  int_1 = atoi(split);
  split = strtok(NULL, ",");
  int_2 = atoi(split);
  split = strtok(NULL, ",");
  int_3 = atoi(split);
 split = strtok(NULL, ",");
  int_4 = atoi(split);
 split = strtok(NULL, ",");
  int_5= atoi(split);
 
 Serial.println( int_1);
 Serial.println(int_2);
 //Serial.println(int_3);
//Serial.println(int_4);
//Serial.println(int_5);

}
1 Like