2009-11-24 5 views
7

Je crée une horloge alimentée par Arduino et, dans le processus, j'essaye de formater des entiers en chaînes formatées à deux chiffres pour la lecture du temps (par exemple 1 en "01").Formatage de chaîne Arduino Problème

Ce qui suit me donne "erreur: l'expression primaire attendue avant '{' jeton":

char * formatTimeDigits (int num) { 
    char strOut[3] = "00"; 
    if (num < 10) { 
    strOut = {'0', char(num)}; 
    } 
    else { 
    strOut = char(num); 
    } 
    return strOut; 
} 

Je suis en train de l'utiliser comme suit:

void serialOutput12() { 
    printWeekday(weekday); // picks the right word to print for the weekday 
    Serial.print(", "); // a comma after the weekday 
    Serial.print(hour12, DEC); // the hour, sent to the screen in decimal format 
    Serial.print(":"); // a colon between the hour and the minute 
    Serial.print(formatTimeDigits(minute)); // the minute 
    Serial.print(":"); // a colon between the minute and the second 
    Serial.print(formatTimeDigits(second)); // the second 
} 

Toutes les idées qu'est-ce qui me manque ici?

Répondre

8

La syntaxe d'accolade est valide pour la déclaration initiale d'une variable, mais pas pour l'affectation après le fait.

En outre, vous renvoyez un pointeur vers une variable automatique qui n'est plus validement allouée une fois retournée (et qui sera écrasée par l'appel suivant, par exemple print). Vous devez faire quelque chose comme ceci:

void formatTimeDigits(char strOut[3], int num) 
{ 
    strOut[0] = '0' + (num/10); 
    strOut[1] = '0' + (num % 10); 
    strOut[2] = '\0'; 
} 

void serialOutput12() 
{ 
    char strOut[3]; // the allocation is in this stack frame, not formatTimeDigits 

    printWeekday(weekday); // picks the right word to print for the weekday 

    Serial.print(", "); // a comma after the weekday 

    Serial.print(hour12, DEC); // the hour, sent to the screen in decimal format 

    Serial.print(":"); // a colon between the hour and the minute 

    formatTimeDigits(strOut, minute); 
    Serial.print(strOut); // the minute 

    Serial.print(":"); // a colon between the minute and the second 

    formatTimeDigits(strOut, second); 
    Serial.print(strOut); // the second 
} 
+0

Ok merci! Étant habitué à C#, j'imagine que je supposais qu'il ferait passer une référence à la fonction (eek). – amb9800

+0

Il (votre exemple original) * renvoie * une référence, mais à un objet qui cesse d'exister après la sortie de la fonction (il devient donc une référence qui se balance). C n'a pas de comptage de référence/de récupération de place intégré. – caf

1

En C, vous ne pouvez pas définir directement le contenu d'un tableau avec l'opérateur d'affectation = (vous pouvez initialiser un tableau, mais c'est une autre chose, même si elle semble similaire).

De plus:

  • Il ne ressemble pas à la fonction de câblage char(value)/opérateur fait ce que vous voulez; et
  • Si vous souhaitez renvoyer un pointeur sur ce tableau strOut, vous devrez lui donner une durée de stockage statique.

La façon simple de faire ce que vous voulez est sprintf:

char * formatTimeDigits (int num) 
{ 
    static char strOut[3]; 

    if (num >= 0 && num < 100) { 
    sprintf(strOut, "%02d", num); 
    } else { 
    strcpy(strOut, "XX"); 
    } 

    return strOut; 
} 
+0

Je ne pense pas que 'sprintf' fasse partie de la librairie Arduino - les librairies sont brutalement sous-dimensionnées pour correspondre à une taille de segment de texte maximale de 14ko. –

+1

Jeffrey Hantin: J'ai vu des exemples qui impliquent que c'est le cas, mais qui n'ont pas de support de virgule flottante lié par défaut. – caf

0

Un couple de choses:

  • Vous ne pouvez pas attribuer à un tableau: strOut = {'0', (char)num};
  • Vous renverront l'adresse un objet qui cessera d'exister juste après la déclaration de retour.

Pour le premier problème, assignent aux éléments du tableau:

strOut[0] = '0'; 
strOut[1] = num; 
strOut[2] = '\0'; 

Pour le 2ème problème, la solution est un peu plus compliqué. Le mieux serait de passer une chaîne de destination à la fonction FormatTimeDigits() et de laisser l'appelant s'inquiéter à ce sujet.

FormatTimeDigits(char *destination, int num); /* prototype */ 
FormatTimeDigits(char *destination, size_t size, int num); /* or another prototype */ 

Encore un autre point sur le 1er point: vous avez pu voir quelque chose de similaire dans une initialisation . C'est différent de l'affectation, et cela permet une construction similaire à l'affectation.

char strOut[] = {'a', 'b', 'c', '\0'}; /* ok, initialization */ 
strOut = {'a', 'b', 'c', '\0'}; /* wrong, cannot assign to array */ 
+0

Ouais, j'avais adapté la syntaxe de parenthèse d'une initialisation que j'ai vu dans un échantillon. Est-il possible d'attribuer plusieurs valeurs dans un tableau dans une instruction? – amb9800

+0

Il est impossible d'affecter plusieurs éléments de tableau dans une instruction "simple". Mais, comme vous avez affaire à des chaînes, vous pouvez utiliser des fonctions de chaînes, comme dans 'strcpy (strOut," 00 "),' ou 'strcat (strOut," 00 ");' ou 'sprintf' ... – pmg