Printing text and string variable

Hi there! I am trying for the Serial Monitor to print out: Does [i.name] need to be in:

I've coded the following:

Serial.println("Does " + i.name + " need to be in:");

However, it prints out the following:
Does
[i.name]
need to be in:

How can I get for the monitor not to print it out with the newlines?

Thanks!

What's arduino board you using?

I am wonder how do you print anything at all?
As a rule, you can't use "+" sign as a connection between print statements.

1 Like

What exactly is i.name and where does it come from ?

I am using Arduino Uno but want to print in the Serial Monitor

struct plant {
 String name;
 int hum;
 int temp;
 int light;
};
Serial.println("How many plants would you like to keep track of?");
  serial = Serial.available();
  while (true) {
    if (Serial.available() != serial) break;
  }
  int no_plants = Serial.parseInt();
  plant p[no_plants] = {};
// For every plant, we prompt the user for its parameters
  for (int j = 0; j < no_plants; j++) {
    plant i;
    Serial.print("What is the name of plant ");
    Serial.print(j + 1);
    Serial.println("?");
    serial = Serial.available();
    while (true) {
      if (Serial.available() != serial) break;
    }
    i.name = Serial.readString();
    Serial.println();
    Serial.println("Does " + i.name + " need to be in:");
    Serial.println("1. Dry soil");
    Serial.println("2. Humid soil");
    Serial.println("3. In water");
    serial = Serial.available();
    while (true) {
      if (Serial.available() != serial) break;
    }
struct plant
{
    String name;
    int hum;
    int temp;
    int light;
};

You can't use a String in a struct, You could, however, use a C style string (lowercase s)

You sure can. In C++, a struct is virtually identical to a class but with public access by default.

@sergiruestes: to answer your question directly, if you want the whole string to print without a newline at the end, use Serial.print instead of Serial.println (the ln means "line"). If i.name contains a newline, you'll need to remove that somehow before printing it (or avoid adding the newline in the first place while you're reading the name over serial).

depending on the setting of your serial monitor, you send also the CR/LF via Serial into the variable. Therfore you will get the CR/LF also in your printout.

Modify your serial Monitor to NOT send a line ending.

Try removing all surrounding whitespace, including any newline, after reading the input

    i.name = Serial.readString();  // existing statement
    i.name.trim();                 // add this

Unlike in other languages, with Arduino, String::trim() "modifies the String in place rather than returning a new one"; it returns nothing (void).

BTW, where are they teaching to check for serial input like this

It's overly complicated and wrong if there actually was something immediately available. Might as well also make sure the input is not completely blank, like if they just press Enter. And for prompts like this, read just one line at a time in case a bunch of input got pushed through. More like

  do {
    while (!Serial.available());
    i.name = Serial.readStringUntil('\n');
    i.name.trim();
  } while (!i.name.length());

Why not?

My mistake.

It seems that you can use a String as a member of a struct. I was sure that I remembered problems with it, but it seems not

I typically use structures for data transfers..
Strings in the structures, make it more difficult to serialize and stream..

~q

I think it requires the use of the Standard Template Library (STL).

It's not implemented as part of the IDE for the avr boards because of memory issues.

https://forum.arduino.cc/t/structures-can-a-string-be-part-a-member-in-struct/293589/8

This seems to work on a classic Nano

struct aStruct
{
    byte aByte;
    String aString;
    int anInt;
};

aStruct anExample;

void setup()
{
    Serial.begin(115200);
    anExample.aString = "hello";
    Serial.println(anExample.aString);
}

void loop()
{
}

Sure..
but i was thinking more like..

Serial.write((uint8_t*)&anExample,sizeof(anExample));

~q

ESP32 at least has a handy buffer log function

  struct {
    String s13z = "thirteen char";
    String s14z = "fourteen chars";
  } someStrings;

  Serial.printf("sizeof(2 String): %d\n", sizeof(someStrings));
  log_buf_i((const uint8_t *)&someStrings, sizeof(someStrings));
  Serial.printf("someStrings: %p\n", &someStrings);
  Serial.printf("       s13z: %p c_str: %p\n", &someStrings.s13z, someStrings.s13z.c_str());
  Serial.printf("       s14z: %p c_str: %p\n", &someStrings.s14z, someStrings.s14z.c_str());

which prints (scroll all the way to right if necessary)

sizeof(2 String): 32
/* 0x0000 */ 0x74, 0x68, 0x69, 0x72, 0x74, 0x65, 0x65, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x00, 0x00, 0x8d,    // thirteen char...
/* 0x0010 */ 0xd0, 0x8e, 0xfb, 0x3f, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,    // ...?............
someStrings: 0x3ffb224c
       s13z: 0x3ffb224c c_str: 0x3ffb224c
       s14z: 0x3ffb225c c_str: 0x3ffb8ed0

This is an implementation detail and could vary between boards and versions

  • a String is 16 bytes
    • (coincidentally the same bytes per line as log_buf_?)
  • if the encoded characters plus terminating NUL are 14 bytes or less, they fit "inside" the String
    • along with the string length, with the high bit set
  • otherwise the NUL-terminated characters are outside the String (heap? String pool?)
    • with the String holding a pointer and the length

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.