2011-12-07 72 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的一部分,否則您將解決完全不同的問題。

相關問題