2016-01-13 82 views
1

之間我一直試圖解決它半天......沒有成功...功能的加入字符數組含附加的符號在

我有一個結構:

typedef struct s_iomodus { 
const char* SENSOR; 
const char* POSITION_1; 
const char* SHOW_MI; 
const char* POSITION_2; 
const char* TYPE_1; 
const char* TYPE_2; 
const char* DESCRIPTION; // LOC Description of the 
const int NRVALUES; 
} iomodus_t; 

iomodus_t iomodus[] = { 
{ "Relay","WW_Tank","WW_Pumpe_An_Aus","NO_P2","NO_T1","NO_T2" ,"MAGNETIC", 1}, //D25 : 
{ "Relay","Puffer_Tank","NO_SHOW","NO_P2","NO_T1","NO_T2" ,"SSR", 1}, //D26 : 
{ "Relay","WW_Tank","Valve","Auslauf_unten","Zu","Auf" ,"MAGNETIC", 2}, //D27 : 

其中i存儲所有引腳和位置,這是我送的話題MQTT服務器的所有現狀設置..

現在我有此數組中建立一個字符串在VOID SETUP其發送的

void setup() 
{ 
    Serial.begin(115200); 

    MQTTclient.setServer(server, 1883); 
    MQTTclient.setCallback(callback); 
    Ethernet.begin(mac, ip); 
    // Allow the hardware to sort itself out 
    delay(1500); 

const char *c_topic = concat_strings(iomodus[i].POSITION_1,iomodus[i].SENSOR, iomodus[i].POSITION_2); 

     Serial.println(c_topic); 
     MQTTclient.publish(c_topic, iomodus[i].VERSION); 

    } 

我的問題是...該功能沒有製作正確的字符串 它不在中間添加「/」! 它應該是這樣的字符串: 「MQTTTOPIC_PREFIX/TEXT_str1/TEXT_str2/TEXT_str3」 或 「MQTTTOPIC_PREFIX/TEXT_str1/TEXT_str2/TEXT_str3/TEXT_str4」 如果STR4是存在/不爲空

const char *concat_strings(const char *str1, const char *str2, const char *str3,const char *str4) 
{ 
    // define a buffer 
    static char result[MAX_CONCAT_LEN] = {0}; 

    // counter part 
    int i = 0; 
    const char *slash = {"/"}; 
    const char *PREF= {MQTTTOPIC_PREFIX}; 
    size_t len = strlen(PREF)+strlen(str1)+strlen(str2)+strlen(str3); 

    // loop until end of ID has reached or destination buffer is full 
    while(*PREF && i < MAX_CONCAT_LEN) 
    {result[i++] = *PREF++;} 
    // loop until end of string 1 has reached or destination buffer is full 
    while(*str1 && i < MAX_CONCAT_LEN) 
    {result[i++] = *str1++;} 
    // loop until end of string 2 has reached or destination buffer is full 
    while(*str2 && i < MAX_CONCAT_LEN) 
    {result[i++] = *str2++;} 

if (str3==TRUE){ 
// loop until end of SLASH has reached or destination buffer is full 
    while(*slash && i < MAX_CONCAT_LEN) 
    {result[i++] = *slash++;} 
    while(*str3 && i < MAX_CONCAT_LEN) 
    { result[i++] = *str3++;} 
    }  

if (str4==TRUE){ 
// loop until end of SLASH has reached or destination buffer is full 
    while(*slash && i < MAX_CONCAT_LEN) 
    {result[i++] = *slash++;} 
    while(*str4 && i < MAX_CONCAT_LEN) 
    { result[i++] = *str4++;} 
    }  

    result[len+1] = 0; 

    return result; 
} 

所以即使我這樣做...它不會添加「/」,並且不想識別,如果str3或str4是假...

請問,什麼是最簡單的方法來加入數組和如果str3或str4可用,則添加「/」(str1和str2始終存在)

預先感謝您!

+0

這將是一個容易得多,如果你可以使用'的std :: string's。你可以使用它們嗎? – NathanOliver

+1

@NathanOliver我很想首先提出同樣的建議。我認爲[tag:arduino]不同,它並不是真正的標準C++。 –

+0

_ @ Max_爲什麼不簡單地使用['strcat()'](http://en.cppreference.com/w/c/string/byte/strcat)? –

回答

1

有在代碼中幾個問題:

  • 首先,這將是更好的聲明result功能外:

    static char result[MAX_CONCAT_LEN] = {0}; 
    
  • 聲明函數與str4默認值:

    const char *concat_strings(const char *str1, const char *str2, const char *str3,const char *str4 = NULL); 
    
  • 做不TRUE比較char*,使用NULL代替:

    if (str4 != NULL){ 
    
  • 之間PREFstr1str2,沒有代碼添加分隔符:

    while(*PREF && i < MAX_CONCAT_LEN) 
        {result[i++] = *PREF++;} 
    // loop until end of string 1 has reached or destination buffer is full 
    while(*str1 && i < MAX_CONCAT_LEN) 
        {result[i++] = *str1++;} 
    // loop until end of string 2 has reached or destination buffer is full 
    while(*str2 && i < MAX_CONCAT_LEN) 
        {result[i++] = *str2++;} 
    
  • str4slash指向到字符串的末尾由於:

    while(*slash && i < MAX_CONCAT_LEN) 
        {result[i++] = *slash++;} 
    

    在上一個循環中。 (你通常不需要一個循環這裏,除非分隔符可以在未來的多個字符)

  • len未調整時str4存在:

    size_t len = strlen(PREF)+strlen(str1)+strlen(str2)+strlen(str3); 
    
    result[len+1] = 0; 
    

    它可以切斷str4無論如何。

如果可能的話,這將是最好使用String class,或strcat()

有關Arduino String類的字符串級聯的一些示例,請參見here,herehere

// adding a constant integer to a string: 
    stringThree = stringOne + 123; 

    // adding a constant long interger to a string: 
    stringThree = stringOne + 123456789; 

    // adding a constant character to a string: 
    stringThree = stringOne + 'A'; 

    // adding a constant string to a string: 
    stringThree = stringOne + "abc"; 

    // adding two Strings together: 
    stringThree = stringOne + stringTwo; 
+0

我知道arduino有一些字符串的propriatetary實現。好點子。 –

+0

@Danny_ds:對不起...沒有與字符串庫工作呢...它會如何與你的建議?先謝謝你! – Max

+1

@Max - 類似於:'String stringOne = String(stringTwo +「with more」);//連接兩個字符串' - 參見[這裏](https://www.arduino.cc/en/Reference/StringConstructor)的一些例子,或[這裏](https://www.arduino.cc/en/Tutorial/StringConstructors)的教程。 –

1

我假設你堅持使用C功能和const char*字符串。有幾個更有用的C字符串函數,如strlenstrcopy。正如您將從C API注意到的那樣,在處理原始字符串char*時,標準做法是發出函數應將其結果寫入其中的緩衝區,因此明確清理字符串的責任(在這種情況下:來電者!)。因此,你可以做以下(測試here):

// Example program 
#include <iostream> 
#include <string> 
#include <cstring> 

bool strconcat(char* result, unsigned int bufsize, const char* s1, const char* s2, const char* s3, const char* s4) { 
    const char* strings[4] = {s1, s2, s3, s4}; 
    for(unsigned char i = 0; i < 4; ++i) { 
     const char* s = strings[i]; 
     if(!s) 
      return true; 
     unsigned int len = strlen(s); 
     if(len > bufsize) 
      return false; 
     strcpy(result, s); 
     bufsize -= len * sizeof(char); 
     result += len * sizeof(char); 
     if(i < 3 && strings[i+1]) { 
      if(bufsize > 0) { 
       result[0] = '/'; 
       --bufsize; 
       ++result; 
      } 
      else 
       return false; 
     } 
    } 
    return true; 
} 

int main() 
{ 
    char result[80] = {0}; 
    const char* a = "ab"; 
    const char* b = "xyziuehfih"; 
    const char* c = "ihihfeih"; 
    strconcat(result, 80, a, a, b, 0); 
    std::cout << result << "\n"; 
} 
+0

感謝像魅力一樣工作... heve重寫我的代碼...我將在以後提供反饋,當它使用整個代碼時......謝謝! – Max