String manipulation in arduino IDE - Noob question

No matter how I approach this, I'm wrong. I'm so used to being able to take things off the beginning/ending of strings at will, and I just can't figure this out in C.

I can build the string I want...

String campus = "mycampus";
String building = "mybuilding";
String room = "office";
String subscription = campus+"/"+building+"/"+room+"/"+"#";

It Serial.prints fine, however, I can't use it in a function call like

      client.subscribe(subscription);

I get "no matching function for call to 'PubSubClient::subscribe(String&)'"

How do I use this concatenated string in my function call?

Putting

  client.subscribe("mycampus/mybuilding/office/#");

works just fine.

Looks like you're passing a String object (subscription) while the sign of the method:
subscribe(String&)
is telling us the method wants an address of a String object (String**&**).
This should work:

client.subscribe(&subscription);

By the way, you should switch to char arrays instead of String objects (ref).

Try double quotes around the whole subscription and single quotes for the /

Goet:
This should work:

client.subscribe(&subscription);

That didn't work @Goet. Same error.

Goet:
By the way, you should switch to char arrays instead of String objects (ref).

Switching from String to char gave me the error
invalid operands of types 'const char*' and 'const char [2]' to binary 'operator+'

INTP:
Try double quotes around the whole subscription and single quotes for the /

If I try your suggestion with the variable types as char...

@INTP. Doing that with $subscription made it compile, but nothing worked.
Removing the & made it stick in some sort of loop that it doesn't do when the text is in there instead of the variable.

If I try it with the variable type as Serial I get
no matching function for call to 'PubSubClient::subscribe(String*)'

Sorry. This is maddening.

I'm away from my pc and have no way of testing this. But it compiles on my app.

String campus = "mycampus";
String building = "mybuilding";
String room = "office";
String subscription = campus+"/"+building+"/"+room+"/"+"#";


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

void loop(){
    test(subscription);
}

void test(String t){
    Serial.println(t);
}

Delta_G:
You're trying to call a method that probably expects a char array (a string) and passing it a String object (capital S). I think the String class has a method to get the underlying char array out of it, but you should really just ditch the String class all together and build your strings with char arrays. String on a limited environment like a microcontroller can cause some weird bugs.

Every time I try to use chars, I get even crazier errors. Can you give an example of how I would concatenate something like that?

DangerToMyself:
I'm away from my pc and have no way of testing this. But it compiles on my app.

Yeah. I have a completely separate sketch called string manipulation that I can get to compile. I just can't take that variable and pass it to the function. If someone could explain how to do it with char, that would be awesome.

mudmin:
Yeah. I have a completely separate sketch called string manipulation that I can get to compile. I just can't take that variable and pass it to the function. If someone could explain how to do it with char, that would be awesome.

So, the "method" I used outputs nothing? Well, I'll try to remember that if I ever need something similar.

String campus = "mycampus";
String building = "mybuilding";
String room = "office";
String slash = "/";
String subscription = campus+slash+building+slash+room+slash;

?

I've only ever used char arrays, just looked at the String object reference guide.

      client.subscribe(subscription.c_str());
char *campus = "mycampus";
char *building = "mybuilding";
char *room = "office";
char *slash = "/";
char subscription[80];

strcpy(subscription, campus);
strcat(subscription, slash);
strcat(subscription, building);
strcat(subscription, slash);
strcat(subscription, room);
strcat(subscription, slash);

client.subscribe(subscription);

No Strings used.

PaulS:

char *campus = "mycampus";

char *building = "mybuilding";
char *room = "office";
char *slash = "/";
char subscription[80];

strcpy(subscription, campus);
strcat(subscription, slash);
strcat(subscription, building);
strcat(subscription, slash);
strcat(subscription, room);
strcat(subscription, slash);

client.subscribe(subscription);




No Strings used.

This seems like the right answer but right before that last
strcat(subscription, slash);

My compiler fails and says
expected constructor, destructor, or type conversion before '(' token

I can't see anything out of the ordinary to throw an error there.

Whandall:

      client.subscribe(subscription.c_str());

This actually works! Thank you! It works and the function functions when paired with

String campus = "campus;
String building = "building";
String room = "office";
String subscription = campus+'/'+building+'/'+room+'/'+'#';

Everyone keeps telling me to use char instead of string, but none of those answers will compile, much less get the function to fire properly.

Everyone keeps telling me to use char instead of string, but none of those answers will compile, much less get the function to fire properly.

We can't see your code that uses strings, or the error messages (the EXACT error messages, with line numbers) that you get.

But, feel free to keep ignoring the advice to learn to use strings. Strings are fine, until they bite you in the ass. Then, you WILL need to learn to use strings. Or, you could learn to use them now, and not need to see the doctor for stitches and bandages when it does happen.

PaulS:
We can't see your code that uses strings, or the error messages (the EXACT error messages, with line numbers) that you get.

But, feel free to keep ignoring the advice to learn to use strings. Strings are fine, until they bite you in the ass. Then, you WILL need to learn to use strings. Or, you could learn to use them now, and not need to see the doctor for stitches and bandages when it does happen.

I appreciate this. I really do. I'm learning c as I go. I never know if I'm giving too much or too little information when I ask a question.

Also, I've decided to take a class on C. I do want to learn it properly from the ground up.

Finally, it's not that I don't read the documentation. I'm just at this stage where I don't know what I don't know and I appreciate people who take the time to answer questions constructively.

I also want to add...it's not that I'm just choosing to use String just to spite everyone in the forum.

It's that I've tried everyone's solutions for what seems like one of the most basic things anyone could want to do in coding in any language and it either doesn't compile or the function doesn't work.

It's that I've tried everyone's solutions for what seems like one of the most basic things anyone could want to do in coding in any language and it either doesn't compile or the function doesn't work.

I understand that. What I don't understand is why you won't post the code you say doesn't compile, and the complete error messages, so that you can get help putting the crutches away.

But, I'll get over it.

PaulS:
No Strings used.

Paul, I REALLY appreciate your time. Your code gives me
expected constructor, destructor, or type conversion before '(' token
and the IDE highlights the final

strcat(subscription, slash);

Here is the complete code (that works with String, but will not work with char)

#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <stdlib.h>



#define ONE_WIRE_BUS 11
int resolution = 10; //.5 celcius
#define DEVICE "OfficeArduino"
#define DEVICEHELLO "OfficeArduino Connected"
//String campus = "campus";
//String building = "building";
//String room = "office";
//String subscription = campus+'/'+building+'/'+room+'/'+'#';
String test;
char *campus = "mycampus";
char *building = "mybuilding";
char *room = "office";
char *slash = "/";
char subscription[80];

strcpy(subscription, campus);
strcat(subscription, slash);
strcat(subscription, building);
strcat(subscription, slash);
strcat(subscription, room);
strcat(subscription, slash);

float setpoint = 45.00;
float actual = 44.44;
int state = 0;
int request = 0;
long lastMsg = 0;
float temp = 0;

char *cstring;
byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 221);
IPAddress server(192, 168, 0, 222);

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

DeviceAddress office = { 0x28, 0xFF, 0x46, 0x82, 0x58, 0x16, 0x04, 0x9A };

void callback(char* topic, byte* payload, unsigned int length) {
  for (int i=0;i<length;i++) {
    payload[length] = '\0';
    
    cstring = (char *) payload;
  }
  Serial.println(topic);
  Serial.println(cstring);
  setpoint = atof(cstring);
  Serial.println("The setpoint is...");
  
}

EthernetClient ethClient;
PubSubClient client(ethClient);

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(DEVICE)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic",DEVICEHELLO);
      // ... and resubscribe
      client.subscribe(subscription.c_str());
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup()
{
  
  // disable SD card if one in the slot
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);
  Serial.begin(57600);
    sensors.begin();
    sensors.setResolution(office, resolution);
  
  client.setServer(server, 1883);
  client.setCallback(callback);
  
  Ethernet.begin(mac, ip);
  // Allow the hardware to sort itself out
  delay(1500);
  
}

void loop()
{
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
long now = millis();
  if (now - lastMsg > 60000) {
    lastMsg = now;
    sensors.requestTemperatures(); // Send the command to get temperatures
    temp = sensors.getTempF(office);
    Serial.println(temp);
    if (temp == -127.00) {
    Serial.println("error");
 } else {
      //client.publish("mytopic", String(temp).c_str(),TRUE);
      client.subscribe(subscription);
      }
  }
}

Delta_G:
The code PaulS gave you wasn't a complete program. The parts with strcpy and strcat need to be inside a function. They can't be out at global scope.

I see. So why did only the last one throw an error in the compiler? How would I do that in a function?