我在Arduino的一个名为WiServer.h
的文件中有以下功能。
GETrequest(uint8* ipAddr, int port, char* hostName, char* URL);
现在问题是我需要将一个int值(setting1)连接到char*
URL参数,例如下面的内容。
"twittermood.php?status=sendTweet&setting1="+setting1
我收到错误:
从const char *到char *
的无效转换
我该如何解决?
答案 0 :(得分:9)
你已经获得了不错的通用C ++建议,但对于8位AVR微控制器上Arduino的特殊情况,我认为你需要特定于平台的建议:
Arduino运行时提供String对象。您的问题可能由these examples涵盖。
由于Arduino上的RAM空间非常有限,因此通常使用特殊属性将常量字符串放入闪存(本质上是ROM)中,这需要不同的指令才能访问。使用GCC构建的AVR代码通常构建在AVR Libc之上,它支持对常量字符串和RAM字符串的混合操作。您必须明确代码并选择正确的操作。这至少需要基本了解C字符串的工作方式以及指针的工作方式。我不确定Arduino字符串会自动提供多少这种聪明才智,但如果没有这种聪明,所有字符串常量最终都会在启动时复制到RAM中,并且会一直占用这些宝贵的字节。
如果RAM空间成为问题,或者您正在使用广泛的字符串操作的AVR应用程序,您需要学习如何使用PGM Space operations的混合(可以在flash中使用只读字符串的字符串函数) )和regular C-style RAM-based string operations。
答案 1 :(得分:6)
使用 std::string
,而不是C字符串。使用 字符串流 ,而不是尝试将非字符串值连接到字符串:
std::ostringstream oss;
oss << "twittermood.php?status=sendTweet&setting1=" << setting1;
use(oss.str()); // or use(oss.str().c_str());
如果该API确实需要一个非const
字符串(假设它甚至不占用字符串的长度,我认为它只是一个错误的API,无视const
),复制字符串到缓冲区并传递:
const std::string& str = oss.str();
std::vector<char> buffer(str.begin(), str.end());
buffer.push_back('\0');
GETrequest(addr, port, &buffer[0], c);
至于你做什么时真正发生的事情:
"twittermood.php?status=sendTweet&setting1="
是char[43]
类型的 rvalue , 隐式转换为 const char*
, 指向第一个字符的指针 。为此你添加一个整数,通过这个形成一个const char*
类型的新指针指向一些或多或少随机的内存位置 。我想您尝试将此作为char*
传递给您的API函数, 必须删除const
。
然而,C ++编译器永远不会隐式地删除const
- 为了您自己的利益。
答案 2 :(得分:2)
使用std :: string而不是char *来完成这类工作。 C中的char *是非常基本的,如果你不熟悉C的工作原理,那么使用起来很容易。
如果需要使用char *,请查看strcpy,strcat和snprintf。但是这些功能在初学者手中非常危险,并且可能导致内存损坏和崩溃。
答案 3 :(得分:1)
您可以使用ostringstream
:
#include <sstream>
// ...
std::ostringstream os;
os << "twittermood.php?status=sendTweet&setting1=" << setting1;
GETrequest(addr, port, hostname, os.str().c_str());
答案 4 :(得分:1)
使用std::string
代替char*
,可能使用std::stringstream
进行连接。但首先是关于你的错误:
您的问题是,"twittermood.php?status=sendTweet&setting1="
会为您const char*
,但不能将其隐含地转换为char*
。如果您确定GETrequest
未尝试更改其URL
参数的值,则可以在const_cast<char*>(...)
变量上使用const char*
来丢弃常量。但是,只有当你完全确定它不会被改变时才这样做(不要向编译器说明constness(或任何真正的))。
即使你这样做,"twittermood.php?status=sendTweet&setting1="+setting1
也不会做你认为它做的事情。正如我所说,你的字符串常量会给你一个const char*
,它对字符串操作没有任何了解。因此,向int
添加int
将不会将int
连接到字符串,而是进行一些算术运算,所以如果你很幸运并且你的{{1}}足够小,你只能获得一部分的URL,否则你会解决一些完全不同的东西。
答案 5 :(得分:0)
发布完整性的C解决方案:
const char ctext[] = "twittermood.php?status=sendTweet&setting1=";
char text[sizeof(ctext) + 20];
snprintf(text, sizeof(text), "%s%i", ctext, setting1);
std字符串和流使用起来更好/更安全。