2009-11-24 15 views
7

私はArduino電源の時計を作っていますが、その過程で、整数を2桁のフォーマットされた文字列に変換しようとしています(例えば、 "01"に1)。Arduino String Formatting問題

以下は私に「エラー: 『{』トークン前に、プライマリ・表現予想」:与え、私は次のようにそれを使用しようとしている

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

を:

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 
} 

任意のアイデアをするようここで私は何が欠けているのですか?

答えて

8

中かっこの構文は、変数の初期宣言に有効ですが、事実の後の代入には有効ではありません。

また、自動変数へのポインタは返されます。これは、返された後は有効に割り当てられなくなります(printなどの次の呼び出しで破棄されます)。あなたはこのような何か実行する必要がありますCで

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

ありがとう! C#に慣れているので、関数(eek)への参照を渡すと仮定していたと思います。 – amb9800

+0

(あなたのorignalの例)*は*参照を返しますが、関数が終了した後に存在しなくなったオブジェクトに参照を返します(したがって、参照がぶら下がります)。 Cには参照カウント/ガベージコレクションが組み込まれていません。 – caf

1

を、あなたが直接(あなたが配列を初期化することができますが、それもそれも、異なることだ=代入演算子と配列の内容を設定することはできません同じように見える)。さらに

  • それはchar(value)機能/操作者は、何をしたいん配線のような音はありません。
  • そのstrOut配列へのポインタを返す場合は、静的な記憶期間を持たせる必要があります。

あなたが欲しいものを行うための簡単な方法が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

私は 'sprintf'がArduinoライブラリの一部だとは思わない - libsは14kbの最大テキストセグメントサイズに収まるように残酷にサブセット化されている。 –

+1

Jeffrey Hantin:私は、それがそうであることを暗示するいくつかの例を見ましたが、浮動小数点サポートはデフォルトでリンクされていません。 – caf

0

カップルの事:

  • あなたは、アレイに割り当てることはできません。strOut = {'0', (char)num};
  • あなたはのアドレスを返しますreturn文の直後に存在しなくなるオブジェクト。最初の問題のため

、配列要素に割り当てる:第2の問題について

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

を、溶液が少し複雑です。最良の方法は、宛先文字列をFormatTimeDigits()関数に渡し、呼び出し元にそれを心配させることです。第一項目の

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

さらに別のポイント:あなたが初期で似何かを見ている可能性があります。これは代入とは異なり、代入と同様の見た目の構成が可能です。

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

ええ、サンプルで見た初期化のブラケットシンタックスを修正しました。 1つのステートメントで複数の値を配列に割り当てる方法はありますか? – amb9800

+0

複数の配列要素を1つの "単純な"ステートメントに割り当てる方法はありません。しかし、文字列を扱う際には、 'strcpy(strOut、" 00 ");や' strcat(strOut、 "00");や 'sprintf'のように文字列関数を使うことができます。 – pmg