2011-12-07 110 views
1

我有一个文件,下面的函数调用WiServer.h的Arduino的。从为const char *添加到C *的无效转换为char *”

GETrequest(uint8* ipAddr, int port, char* hostName, char* URL); 

现在的问题是我需要连接一个int值(设置1 。)到

"twittermood.php?status=sendTweet&setting1="+setting1 

像下面例如char* URL参数,我得到一个错误:

invalid conversion from const char* to char*

我该如何解决?

+5

既然你不熟悉C++,我会推荐[一本很好的C++入门书](http://stackoverflow.com/q/388242/46642)。 –

+4

在这个世界上,这是不是一个真正的问题?我非常同情所有对经验丰富的C++程序员的反感,他们将无知的Java编程人员释放到C++世界中,并且看到了我对这些代码的分享 - 但根据规则这是一个合法的问题,作为一个SO问题,它不是坏的一个。 – sbi

+0

对于我们的Java程序员来说,从Java到C/C++是非常棘手的。尽管我很想学习C/C++,但我正在Arduino中做一个项目,并用指针来解决这个小问题。我没有想到会得到这样的回应并且反对票,并且基本上被告知F关闭并阅读C++书籍。 – unleashed

回答

9

你已经得到了不错的通用C++的意见,但对于Arduino的对8位AVR单片机的特殊情况下,我认为你需要特定于平台的建议:

Arduino的运行提供了String对象。您的问题可能覆盖these examples

由于Arduino上的RAM空间非常有限,通常使用特殊属性将常量字符串放入闪存(实质上是ROM)中,这需要不同的指令才能访问。使用GCC构建的AVR代码通常建立在AVR Libc之上,支持混合使用常量字符串和RAM字符串。您必须在代码中明确并选择正确的操作。这至少需要对C字符串如何工作以及指针如何工作有基本的了解。我不确定Arduino字符串自动提供了多少这种聪明,但是如果没有这个聪明,所有的字符串常量最终都会在引导时复制到RAM中,并且会一直占用这些宝贵的字节。

如果RAM空间成为问题,或者您是在AVR应用程序已经做了你需要学习如何使用的PGM Space operations混合(字符串函数,可以在闪光灯工作在只读字符串)广泛的字符串操作和regular C-style RAM-based string operations工作。

+0

'+ 1'来自我的平台知识,我们都没有。 – sbi

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); 

至于到底发生了什么WH带你做你要做的:

"twittermood.php?status=sendTweet&setting1="右值的类型char[43],这隐式转换为const char*一个指向第一个字符。为此,你添加一个整数,通过这个形成一个新的指针类型const char*指向一些或多或少的随机存储器位置。我想你会试图将这个作为char*传递给你的API函数,其中const将不得不丢弃

但是,C++编译器绝不会为了您自己的利益而隐式删除const

+0

事实上,这是一个很好的问题,或多或少的错误/不完整的答案。 +1从我这两个非常好的答案和问题(至少它不再是-1) – Francesco

2

对于这类工作,使用std :: string而不是char *。 C中的char *非常基本,如果你不熟悉C的工作方式,很容易使用错误。

如果您需要使用char *,请查看strcpy,strcat和snprintf。但是这些功能在新手的手中非常危险,并且可能导致内存损坏和崩溃。

+2

不适合Arduino(8位AVR微控制器)。 –

1

您可以使用此一ostringstream:为完整

#include <sstream> 

// ... 

std::ostringstream os; 
os << "twittermood.php?status=sendTweet&setting1=" << setting1; 

GETrequest(addr, port, hostname, os.str().c_str()); 
+0

我认为你的意思是ostringstream。 – StilesCrisis

+0

@StilesCrisis:嗯,当然是......加班打乱了大脑。 :) –

0

发帖℃溶液来:

const char ctext[] = "twittermood.php?status=sendTweet&setting1="; 
char text[sizeof(ctext) + 20]; 
snprintf(text, sizeof(text), "%s%i", ctext, setting1); 

STD字符串和流是好得多/使用更安全。

+1

当然,作为一名程序员,这可以确保你几年后仍然能够找到工作。但是这项工作将会发现如此愚蠢的缓冲区溢出,这使得手机容易感染病毒,而不是写出令人兴奋的新东西。 – sbi

+0

为什么downvote?问题是C风格,所以C答案似乎是合理的。 – Pubby

+1

为什么这个问题?我已经解释过你的代码中存在缓冲区溢出。 (和问题被标记为C++。) – sbi

1

使用std::string而不是char*,也许std::stringstream为您的连接。但首先关于你的错误:

你的问题是,"twittermood.php?status=sendTweet&setting1="会给你一个const char*,它不能被隐式转换为char*。如果您确定GETrequest未尝试更改其参数URL的值,则可以在const char*变量上使用const_cast<char*>(...)来抛弃常量。但是,只有在你确定它不会被改变的时候才能做到这一点(不要在编译器中说明const(或者其他任何东西))。

即使你这样做"twittermood.php?status=sendTweet&setting1="+setting1将不会做你认为它的作用。正如我所说你的字符串常量会给你一个const char*,它没有任何关于字符串操作的知识。因此,将int添加到该字符串将不会将该int连接到该字符串,而是执行一些极点算法,所以如果幸运的话并且您的int足够小,则只会获得URL的一部分,否则您将解决完全不同的问题。

相关问题