アプリ版:「スタンプのみでお礼する」機能のリリースについて

Visual C++初心者です。

000~999までのカウンター表示ができるプログラムがつくりたいのですが

1秒間ごとに1カウントアップします。999の次は000に戻ります。

数値が1桁、もしくは2桁の場合、頭に0を付けて3桁にしなければいけません。

条件として文字列は必ず使わなければいけません。

ltoa(count, temp, 10);
if (temp[2] == '\0' && temp[1] == '\0')  /*数値が1桁の場合*/
{
  temp[2] = temp[0];
  temp[1] = '0';
  temp[0] = '0';
}
if (temp[2] == '\0' && temp[1] != '\0')  /*数値が2桁の場合*/
{
  temp[2] = temp[1];
  temp[1] = temp[0];
  temp[0] = '0';
}

こんな感じのを考えましたが上手くいきませんでした。

0~999までのカウントアップ表示はできております。あとは3桁にするだけなのですが。

よろしくお願いします。

A 回答 (7件)

>これでtemp[3]より後はは常に'\0'になっていると思っているのですが違いますか?



違います。
保証されるのは文字列終端として設定される箇所までです。
「それ以降」の場所は変更されません。

char temp[12];

ltoa(0, temp, 10);
で保証されるのは『temp[0]とtemp[1]まで』で、その後にあるtemp[2~11]は触りません。
そもそもltoa()はドコまでバッファが用意されているのか知りません。
「ここから書き込め」という場所しか指定されていませんから。
セキュリティ拡張版の_ltoa_s()ならサイズも渡しますが…だからといって'\0'を書き込んだ後の部分まで面倒見てくれるワケではないでしょう。

メモリダンプするかltoa()した後でtemp[]配列の内容を全て(16進数でとか)表示してみると判るでしょう。
# VCならブレークポイント設定してメモリウィンドウで確認できるでしょう。


というワケで……temp[]を'\0'で埋める。という処理をしていない状態で
>  temp[2] = temp[0];
>  temp[1] = '0';
>  temp[0] = '0';
とかやると、'\0'がtemp[]内に見つからない。という事態に陥る可能性があります。

よって…
if (temp[2] == '\0' && temp[1] == '\0')  /*数値が1桁の場合*/
1桁だった時にtemp[2]が'\0'になっている保証がありません。
# 事前に'\0'で埋めておかない限りは。
    • good
    • 0
この回答へのお礼

回答有難うございます。

お礼日時:2013/11/24 23:29

#5の方がほぼ正解かと思いますが


for (int i = 2; i <= 0; i--) { ・・・は誤りです。
以下、正しいソースです。
----------------------------------------------
#include <stdio.h>
// 入力値(num=0~999)を3桁の文字列に変換する。
void disp(int num)
{
int i,j;
char temp[4];
temp[3] = '\0';
j = num;
for (i=2; i >= 0; i--){
temp[i] = j % 10 + '0';
j = j / 10;
}
//確認の為
printf("in=%d out=<%s>\n",num,temp);
}
int main()
{
int i;
for (i=0;i<1000;i++){
disp(i);
}
}
--------------------------------------------
disp関数が数値(0~999)を受け取り、文字列に変換しています。
以下、実行結果です。
in=0 out=<000>
in=1 out=<001>
in=2 out=<002>
in=3 out=<003>
in=4 out=<004>
in=5 out=<005>
in=6 out=<006>
in=7 out=<007>
in=8 out=<008>
in=9 out=<009>
in=10 out=<010>
in=11 out=<011>
in=12 out=<012>
途中省略
in=995 out=<995>
in=996 out=<996>
in=997 out=<997>
in=998 out=<998>
in=999 out=<999>
----------------------------
    • good
    • 0
この回答へのお礼

回答有難うございます。

お礼日時:2013/11/24 23:31

> printfやsprintfは使用環境(ソフトウェア)の都合上使えないのです。


ならば、次の内容でどうでしょう。

char temp[4];
temp[3] = '\0';
for (int i = 2; i <= 0; i--) {
temp[i] = '0' + count % 10;
count /= 10;
}

「count を処理の前後で変更したくない」というならば、上記中の count を別変数にし、上記の直前でその別変数に count の値を代入してください。

……まさか、「剰余演算子も使えません」とか言いませんよね?
    • good
    • 0
この回答へのお礼

有難うございます。

早速、試してみます。

お礼日時:2013/11/22 01:04

そもそも「1桁の場合」と「2桁の場合」で同じ条件にする意味がわからん.



100 とか 10 とかで割ればいいじゃん.
    • good
    • 0

#1 ですが、関数名を間違えました。


#1 の printf は sprintf に置き換えてください。
    • good
    • 0
この回答へのお礼

早速回答有難うございます。

printfやsprintfは使用環境(ソフトウェア)の都合上使えないのです。

お礼日時:2013/11/21 23:37

>こんな感じのを考えましたが上手くいきませんでした。



「なにが」「どう」うまく行かないんです?
とりあえず…'\0'考慮していないみたいですがtemp[3]は常に'\0'になってますか?

>数値が1桁、もしくは2桁の場合、頭に0を付けて3桁にしなければいけません。

そういう条件だったらsprintf()とか使いますけどね。
sprintf(temp, "%03d", count);
だけで終わりです。
sprintf()が使えない&数字変換はltoa()でやること。とか条件があるなら…まぁ他の方法をってコトになりますけど。

strcpy(temp, "000");
if(count > 99)
 ltoa(count, temp, 10);
else if(count > 9)
 ltoa(count, &temp[1], 10);
else
 ltoa(count, &temp[2], 10);
とか…
別にバッファ用意できるなら…

strcpy(temp2, "00");
ltoa(count, temp, 10);
strcat(temp2, temp);
strcpy(temp, &temp2[strlen(temp2)-3]);
とか…

この回答への補足

>「なにが」「どう」うまく行かないんです?

私が考えたアルゴリズムだとやっぱり0~999で表示されてしまいます。

>とりあえず…'\0'考慮していないみたいですがtemp[3]は常に'\0'になってますか?
int count = 0;
char temp[12];
if (count < 999)
{
  count++;
}
else if (count >= 999)
{
  count = 0;
}
ltoa(count, temp, 10);
固有表示関数(temp);

これでtemp[3]より後はは常に'\0'になっていると思っているのですが違いますか?

補足日時:2013/11/21 23:55
    • good
    • 0
この回答へのお礼

早速回答有難うございます。

printfやsprintfは使用環境(ソフトウェア)の都合上使えないのです。

if (count < 999)
{
  count++;
}
else if (count >= 999)
{
  count = 0;
}
ltia(count, temp, 10);
固有表示命令(temp);

こんな感じで0~999は表示できました。

使用上どうも最終的に文字列にしないと表示できないみたいです。

お礼日時:2013/11/21 23:47

つ printf(temp, "%03d", count);

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!