Arduino char* 数组[] : "vanishing" 个字符

Arduino char* array[] : "vanishing" characters

本文关键字:vanishing 字符 char 数组 Arduino      更新时间:2023-10-16

我使用char*数组[]来存储串行打印数据。

然而,数据正在从数组中"消失"。

当我多次打印同一个var时,问题似乎就出现了。

串行输出:

Hello world !
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
0 - Archivage de : Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Affichage de l'historique : 
0Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
1 - Archivage de : Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Affichage de l'historique : 
0Lorem ip
1Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
2 - Archivage de : Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Affichage de l'historique : 
0Lorem ip
1Lore
2Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Affichage de l'historique : 
0Lorem ip
1Lore
2Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Arduino草图:

#include <SPI.h>
#include <Ethernet.h>
#include <shutterSerial.h>
ShutterSerial s = ShutterSerial();
void setup() {
  s.begin(115200);
  s.setVerboseLevel(DEBUG);
  String test("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
  s.print("Hello world !", INFO, true);
  s.print(test, INFO, true);
  s.print(test, INFO, true);
  s.print(test, INFO, true);

  s.historique_print();
}

void loop() {
}

shutterSerial.h

#ifndef shutterSerial
#define shutterSerial
#include <SPI.h>
#define HISTORYSIZE 20
enum Level {
  ERROR,
  INFO,
  STACK,
  DEBUG,
  };
class ShutterSerial {
  public:
    /*Constructeur*/
    ShutterSerial();
    static void begin(unsigned int baudRate);
    static void setVerboseLevel(unsigned int level);
    static unsigned int getVerboseLevel();
    static void print(String msg, int level, bool crlf);
    static void print(int msg, int level, bool crlf);
    static void print(char* msg, int level, bool crlf);
    static void historique_reset();
    /*Historique des messages séries. On ne conserve que les messages d'INFO et d'ERROR*/
    static char* _historique[HISTORYSIZE];
    static void historique_put(char* nouveau);
    static void historique_print();
    static unsigned int _compteur;
    static char* intToCharArray(int value, bool crlf);
  private:
    static Level _verbosite;
};
#endif

shutterSerial.cpp

#include "shutterSerial.h"
ShutterSerial::ShutterSerial() {}
/*Initialisation du niveau de verbosité à INFO*/
Level ShutterSerial::_verbosite = INFO;
char* ShutterSerial::_historique[HISTORYSIZE];
unsigned int ShutterSerial::_compteur = 0;
static char temp[128];

void ShutterSerial::begin(unsigned int baudRate) {
  Serial.begin(baudRate);
  /*Ces deux lignes permettent d'éviter de perdre le premier caractère affiché
  L'arduino à tendance à ne pas afficher le premier caractère.
  */
  while(!Serial);
  Serial.println("");
}
unsigned int ShutterSerial::getVerboseLevel() {
  return (unsigned int)_verbosite;
}
void ShutterSerial::setVerboseLevel(unsigned int level) {
  _verbosite = (Level) level;
}
void ShutterSerial::print(String msg, int level, bool crlf) {
  if(level <= _verbosite) {
    if (crlf) {
      Serial.println(msg);
      if(level <= INFO) {
        msg += "n";
        msg.toCharArray(temp, msg.length());
        historique_put(temp);
      }
    }
    else {
      Serial.print(msg);
      if(level <= INFO) {
        msg.toCharArray(temp, msg.length());
        historique_put(temp);
      }
    }
  }
}
void ShutterSerial::print(int msg, int level, bool crlf) {
  if(level <= _verbosite) {
    if (crlf) {
      Serial.println(msg);
      if(level <= INFO) {
        // historique_put(ShutterSerial::intToCharArray(msg, true));
      }
    }
    else {
      Serial.print(msg);
      if(level <= INFO) {
        // historique_put(ShutterSerial::intToCharArray(msg, false));
      }
    }
  }
}
void ShutterSerial::print(char* msg, int level, bool crlf) {
  if(level <= _verbosite) {
    if (crlf) {
      Serial.println(msg);
      if(level <= INFO) {
        // strcat(msg, "n");
        // historique_put(msg);
      }
    }
    else {
      Serial.print(msg);
      if(level <= INFO) {
        // historique_put(msg);
      }
    }
  }
}

/*Manipulation de l'historique*/
void ShutterSerial::historique_reset() {
  _compteur = 0;
}
void ShutterSerial::historique_put(char* nouveau) {
  Serial.print(_compteur);
  Serial.print(" - Archivage de : ");
  Serial.println(nouveau);
  _historique[_compteur] = (char*)malloc(sizeof(strlen(nouveau) + 1));
  memcpy(_historique[_compteur], nouveau, strlen(nouveau) + 1);
  _compteur = _compteur + 1;
  historique_print();
}
void ShutterSerial::historique_print() {
  int cpt = 0;
  Serial.println("Affichage de l'historique : ");
  if(_compteur > 0) {
    for(cpt = 0; cpt < _compteur; cpt++) {
      Serial.print(cpt);
      Serial.println(_historique[cpt]);
    }
  }
  else {
    Serial.println("L'historique est vide.");
  }
}
char* ShutterSerial::intToCharArray(int value, bool crlf) {
  char* convertedValue = (char*)malloc(sizeof(char));
  if(crlf) {
    sprintf(convertedValue, "%dn", value);
  }
  else {
    sprintf(convertedValue, "%d", value);
  }
  return convertedValue;
}

让我们展开这一行以提高可读性。

_historique[_compteur] = (char*)malloc(sizeof(strlen(nouveau) + 1));
_historique[_compteur] = (char*)malloc(    sizeof( strlen(nouveau) + 1 )    );

这里你取的是sizeof( strlen(nouveau) + 1 ),它等于sizeof(int)

这行应该是:

_historique[_compteur] = (char*)malloc( (strlen(nouveau) + 1) * sizeof(char)  );

我希望它是可读的!