[Résolu] Réaliser une fonction qui renvoie un tableau

Bonsoir à tous,

Je voudrais réaliser une fonction, pour déterminer le nom d'enregistrement d'un fichier dans mon data logger SD. Un fichier d'enregistrement sera réalisé par jour avec une structure du type : "DonnéesRuche_Date.csv"

J'ai créer une fonction Date et un fonction NomFichier qui fonctionne comme ceci :

String Heure()
{
  now = RTC.now();
  
  String sheure = String(now.hour());
  String sminute = String(now.minute());
  String sseconde = String(now.second());

  String sHeure = sheure + ":" + sminute + ":" + sseconde;
  return sHeure;
}

char NomFichier()
{
  String sNomFichier;
  char Buf[30]; 
  sNomFichier = "DonneesRuche_" + Date() + ".csv";
  sNomFichier.toCharArray(Buf, 30);
  return Buf;
}

En fait ce code n'est pas réellement bon, puisque "char NomFichier()" ne renvoi jamais la chaîne de caractères étant contenu dans le buffer.

Ma question est donc comment "définir" ma fonction pour qu'elle me retourne bien l'ensemble des caractères contenu dans "Buf" ? :cold_sweat:

D'avance merci

Ta fonction renvoie buf, qui n'est jamais remplie

Pourtant j'ai déjà mis un "serial.print(Buf)" qui m'écrit bien mon nom de fichier dans le port série !

A la limite la fonction je sais passer au dessus du problème en renvoyant un string.

Maintenant le problème que j'ai c'est dans le code d'ouverture du fichier :

char cNomFichier[30];
  NomFichier().toCharArray(cNomFichier, 30);
  Serial.println(cNomFichier);
  delay (1000);
  myFile = SD.open(cNomFichier , FILE_WRITE);

Le problème de cela c'est que "cNomFichier" a pour valeur DonneesRuche_26-10-2016.csv Moi je voudrais qu'il ai pour valeur "DonneesRuche_26-10-2016.csv"

Comment est ce que je pourrais faire cela ?

char *NomFichier()
{
  String sNomFichier;
  static char Buf[30]; 
  sNomFichier = "DonneesRuche_" + Date() + ".csv";
  sNomFichier.toCharArray(Buf, 30);
  return Buf;
}

C'est pas joli-joli comme code mais ca devrait marcher mieux... ;)

Pour la petite explication : 1) pour renvoyer un tableau il faut renvoyer son adresse, d'où le "char *" comme type de retour de ta fonction ; 2) la portée, ce qui revient à "la validité" de ta variable "Buf" ne s'applique qu'à l'intérieur de ta fonction, ce qui veut dire que tout de suite après ton "return Buf;" en sortant de la fonction, le contenu de "Buf" n'est plus valide : un excellent moyen de faire planter ton programme... 3) en ajoutant "static" à la déclaration de "Buf" cette dernière devient en quelque sorte "globale" et sa "validité" persiste en dehors de ta fonction.

Merci Zorro_X ca me retourne bien mon nom de fichier quand je suis dans la partie "Setup" de mon programme ... j'avance ! ::)

Maintenant ma dernière question, je ne comprends pas pourquoi ce code :

  myFile = SD.open(NomFichier(), FILE_WRITE);
  Serial.println(myFile);
  delay (5000);
  if (myFile) 
  {
    Serial.print("Writing to file ... ");
    myFile.println("date;heure;humidite;temperature");
    myFile.close();
    Serial.println("done");
  } 
  else { Serial.println("error opening file"); }

me renvoi "0" et du coup n'écrit jamais dans mon fichier ...

Hors que ce code :

char datafile[13];
 int jour=now.day();
 int mois = now.month();
 int annee= now.year(); 
 sprintf(datafile,"%02d%02d%04d.csv",jour,mois,annee);
 datafile[13]='\0';


 fichierSD = SD.open(datafile, FILE_WRITE);

me renvoi "1" et du coup écrit bien dans le fichier csv ...

J'imagine que cela vient de la ligne avec "sprintf" mais je comprends pas pourquoi et du coup comment je pourrais le changer dans mon code à moi :-X

sNomFichier = "DonneesRuche_" + Date() + ".csv"; ça fait bcp de caractères si votre carte SD est formatée pour des noms de fichiers courts 8.3

sprintf(datafile,"%02d%02d%04d.csv",jour,mois,annee); ça fait exactement 8.3 pour le nom de fichier donc c’est bon (et 12 caractères tiennent bien dans un buffer de 13 elements, le sprintf rajoute tout seul le ‘\0’ à la fin)

Par contre

char datafile[[color=red]13[/color]];
...
datafile[[color=red][b]13[/b][/color]]='\0';

est une très mauvaise idée… (overflow)

MERCI J-M-L !! :money_mouth_face:

Et dire que je me suis pris la tête comme un con toute l'aprem en pensant que c'était un soucis avec mes déclarations de variable ou autre ... Je n'aurais jamais pensé à cela !

Un grand merci à vous trois en tout cas !

Je reviendrais sans doute vers le forum pour la suite de mon projet prochainement ;D

J-M-L: char datafile[[color=red]13[/color]]; ... datafile[[color=red][b]13[/b][/color]]='\0';

est une très mauvaise idée... (overflow)

Ce code n'était pas de moi, je trouvais ca bizar aussi de faire cela ! Encore merci

Oui parfois on se concentre sur un truc et on oublie des choses... c'est là qu'une paire d'yeux supplémentaires / un regard neuf sur le pb peut aider (et c'est pour ça que la relecture de code est un bon moyen de trouver des bugs dans l'industrie du logiciel)

Le buffer overflow vraiment faut faire attention, un tableau de 13 caractères voit ses indices aller de 0 à 12, donc quand bien même sprintf fait le boulot de mettre le '\0' à la fin et que cela n'est pas nécessaire, c'est en index datafile[12] qu'il faut (et dans ce cas pas la peine) le mettre, pas 13.

Pour le nom du fichier ma recommendation serait année mois jour plutôt que l'inverse comme cela c'est facile ensuite de trier les fichiers par nom pour les avoir de manière chronologique

Bonne continuation!