Arduino WiFiClient Write

166
10 апреля 2019, 03:20

Как правильно, без объявления, переменной собрать строку?

serverClient.write(...)

#define MAX_SRV_CLIENTS 4
WiFiServer server(TELNET_PORT);
WiFiClient serverClients[MAX_SRV_CLIENTS];
void TelnetInit() {
  server.begin();
  server.setNoDelay(true);
}
void TelnetInput()
{
  uint8_t ClientID;
  ...
  if (server.hasClient()) {
    ...
    if (ClientID == MAX_SRV_CLIENTS) {
      WiFiClient serverClient = server.available();
      serverClient.write( "maximum " + MAX_SRV_CLIENTS + " of concurrent connections " );
      serverClient.stop();
    }
  }
}

при сборке вылетает ошибка

serv.ino: In function 'void TelnetInput()':

serv.ino:84:58: error: invalid operands of types 'const char*' and 'const char [25]' to binary 'operator+'

serverClient.write( "maximum " + MAX_SRV_CLIENTS + " concurrent connections\n" );

Answer 1

Нужно привести аргументы к типу, поддерживающему оператор + в нужной интерпретации. В частности можно было бы использовать std::string. Но из-за наличия числа, да и по сути формирования строки лучше использовать строковый поток std::stringstream или вовсе сишную sprintf():

#include <sstream>
std::stringstream ss;
ss << "maximum " << MAX_SRV_CLIENTS << " concurrent connections\n";

ss.str().c_str() вернёт сишную строку, скорее всего нужную для serverClient.write().

Если всё же хочется склеивать строку через +, то нужно как минимум как-то преобразовать число, которое приходит из макроса, в строку. Например, это можно сделать дополнительными макросами же:

#define xstr(a) str(a)
#define str(a) #a
auto s =  std::string("maximum ") + xstr(MAX_SRV_CLIENTS) + " concurrent connections\n";

Или, раз уж C++11 есть, то std::to_string():

std::string("maximum ") + std::to_string(MAX_SRV_CLIENTS) + " concurrent connections\n";

Если не хочется заводить человеческую именованную переменную, и тем не менее нужно передать в функцию сишный указатель, то достаточно последнее выражение обернуть в скобки и вызвать для него c_str():

(std::string("maximum ") + std::to_string(MAX_SRV_CLIENTS) + " concurrent connections\n").c_str()

Но с помощью макроса преобразования в строку и зная о конкатенации строковых литералов, записанных последовательно, можно действительно исключить использование переменной и создание временных строковых объектов:

"maximum " xstr(MAX_SRV_CLIENTS) " concurrent connections\n";

Стоит заметить, что никаких знаков + тут нет, и даже пробелы вокруг макроса xstr не являются обязательными.

READ ALSO
QGraphicsView измение размера мышкой. QT C++

QGraphicsView измение размера мышкой. QT C++

Есть какое-то свойство, которое позволяет растягивать элемент мышкой?

140