Arduino 我如何使用 char 而不是 String (为了更好的内存使用) [英] Arduino How can I use char instead of String (for better memory usage)

查看:22
本文介绍了Arduino 我如何使用 char 而不是 String (为了更好的内存使用)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读过一千遍了,String 库不是代码和内存优化的最佳解决方案.所以我需要使用char而不是String.我有几个函数返回字符串,我将它用于存储在文件(sd 卡)中或将其作为参数发布到网络.因此,在下面的草图中,我如何将其更改为与 char 一起使用.我知道如何保存到 sd 文件或发布到网络服务器.我只需要帮助将字符串更改为字符.

I have read thousand times that String library is not the best solution for code and memory optimization. So I need to use char instead of String. I have several functions that return String where I use it for store in file (sd card) or post it to web as param. So in the following sketch, how can i change it to work with char. I know how to save to sd file or post to webserver. I need only help for change the String to char.

#include <ThreeWire.h>  
#include <RtcDS1302.h>

ThreeWire myWire(7,8,6); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);

#define countof(a) (sizeof(a) / sizeof(a[0]))

String NowDateTime="";

void setup() {
    Serial.begin(9600);       // for debugging
    Rtc.Begin();
    RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
    if (!Rtc.IsDateTimeValid()) {
        Rtc.SetDateTime(compiled);
    }
    if (Rtc.GetIsWriteProtected()) {
        Rtc.SetIsWriteProtected(false);
    }
    if (!Rtc.GetIsRunning()) {
        Rtc.SetIsRunning(true);
    }
    RtcDateTime tempnow = Rtc.GetDateTime();
    if (tempnow < compiled) {
        Rtc.SetDateTime(compiled);
    }
    RtcDateTime now = Rtc.GetDateTime();
    NowDateTime = strDT(now);
    Serial.println((String)"RTC: "+NowDateTime);
}

void loop() {
    delay(1000);
    RtcDateTime now = Rtc.GetDateTime();
    NowDateTime = strDT(now); 
    Serial.println(NowDateTime);
}

//RETURN Datetime id Readeable format as stting
String strDT(const RtcDateTime& dt)
{
    char ret[30];
    snprintf_P(ret, 
            countof(ret),
            PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
            dt.Year(),
            dt.Month(),
            dt.Day(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );     
    return ret;
}

预先感谢您的帮助!!!

Thanks in advance for your help!!!

推荐答案

我知道您的意图是了解如何使用 c 数组而不是 String 类,但是在您的代码中,很容易避免使用 String 和将数组保留在函数内部,使代码更简单、更健壮.

I know your intention is to understand on how to use c array instead of String class, but in your code, it is easy to avoid the use of String and keep the array local within the function to make the code simple and more robust.

您不需要返回字符串,只需将 Serial.print 添加到您的函数末尾即可.

You don't need to return a String, just add the Serial.print to the end of your function.

void loop() {
  RtcDateTime now = Rtc.GetDateTime();
  printDateTime(now);
}

void printDateTime(const RtcDateTime& dt)
{
    char ret[20];
    snprintf_P(ret, 
        countof(ret),
        PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
        dt.Year(),
        dt.Month(),
        dt.Day(),
        dt.Hour(),
        dt.Minute(),
        dt.Second() 
    );
    Serial.println(ret);
}

如果你真的更喜欢让函数返回包含格式化字符串的数组,你可以在函数中将 ret[20] 声明为一个 static 数组,这样从函数调用返回后,数组的值不会被释放.

If you really prefer to have the function to return the array that contained the formatted string, you can declare ret[20] as a static array within the function so that the value of the array won't be free up after returning from the function call.

void loop() {
  RtcDateTime now = Rtc.GetDateTime();
  Serial.println(strDT(now));
}

char* strDT(const RtcDateTime& dt)
{
    static char ret[20];    //local static variable
    snprintf_P(ret, 
        countof(ret),
        PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
        dt.Year(),
        dt.Month(),
        dt.Day(),
        dt.Hour(),
        dt.Minute(),
        dt.Second() 
    );
    return ret;
}

注意到函数的返回类型应该是指向 ret 的点(即 char*).

Noticed that the return type from the function should be a point to the ret (i.e. char*).

String library 你在 Arduino 中看到的不是 C++ 的一部分,它给了 Arduino一些特性,例如python-like 或Java-like concatenation,比如String myString = "This string " + this_var + " another string";,在堆内存中使用动态内存分配malloc.对于刚接触 Arduino 的人来说,它看起来更容易,但它可能会导致堆碎片或内存泄漏,特别是如果一个编程新手并且不真正了解堆是如何工作的.要完全替代使用 Sting 类,最好学习如何使用 C++ cstring.h 处理字符串的函数.

String library you see in Arduino is not part of C++, it gives Arduino some features such as python-like or Java-like concatenation like String myString = "This string " + this_var + " another string";, which use dynamic memory allocation malloc at heap memory. it looks easier for the people who is new to Arduino, it is however could caused heap fragmentation or memory leak especially if one is new to programming and don't really understand how heap works. To complete replace of using Sting class, it is best to learn how to use C++ cstring.h functions to handle string.

这篇关于Arduino 我如何使用 char 而不是 String (为了更好的内存使用)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆