質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.93%

日時を取得して、表示する関数を作成したい

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 205

xeno

score 3

実現したい事

C言語で日時を1文字ずつ取得し、日時を表示する関数を作成したいです。

該当のソースコード

#include <stdio.h>
#include <time.h>

#define STX 0x02    /* テキスト開始 */
#define ETX 0x03    /* テキスト終了 */

static char str[] = "9999年99月99日 99時99分99秒";
static int int_c[] = { 0, 1, 2, 3, 6, 7, 10, 11, 16, 17, 20, 21, 24, 25};    /* 上の配列strの間接的な添え字 */

/*
    名称    timer_data_1
    引数    char timer_str:日時([STX]YYYYMMDDHHMMSS[ETX])の1文字
    戻り値    無し
*/
/*----- ここより下に解答を記述してください -----*/
void timer_data_1(char timer_str)
{
    int i = 0;
    int flag = 0;

    if (timer_str == STX){
        flag = 1;
    }else if (timer_str == ETX){
        printf("%c\n", str);
        flag = 0;
    }else if (flag = 1){
        str[int_c[i]] = timer_str + (i + 1);
        i++;
    }

    return;
}
/*----- ここより上に解答を記述してください -----*/

int main(void)
{
    time_t current;
    struct tm *timer;
    int tm_sec = 0;
    char str[20];
    int i;
    char *str_snd;

    /* 乱数の初期化 */
    srand(time(NULL));
    i = rand() % 15;

    while(1){
        current = time(NULL);
        timer = localtime(&current);
        if(timer->tm_sec != tm_sec){
            *(str + 0) = STX;
            sprintf(str + 1,"%04d%02d%02d%02d%02d%02d",
                    timer->tm_year + 1900,    timer->tm_mon + 1,    timer->tm_mday,
                    timer->tm_hour,            timer->tm_min,        timer->tm_sec);
            *(str + 15) = ETX;
            *(str + 16) = '\0';

            while(*(str+i)){
                timer_data_1(*(str + i));
                i++;
            }

            tm_sec = timer->tm_sec;
            i = 0;
        }
    }

    return 0;
}

表示例

2020年07月16日 17時19分21秒
2020年07月16日 17時19分22秒
2020年07月16日 17時19分23秒
2020年07月16日 17時19分24秒
2020年07月16日 17時19分25秒
2020年07月16日 17時19分26秒
2020年07月16日 17時19分27秒
上のように1秒ずつ表示されるようにしたい

発生している問題・エラーメッセージ

コンパイルエラーは起きていませんが何も表示されません。関数内で、テキスト開始(STX)が来た時の処理、テキスト終了(ETX)が来た時の処理など上手く書けないでいます。どうすれば正しく表示させることができるのか教えてほしいです。

試したこと

関数部分のプログラムは一応書きました。表示例のようにならないけれど
カーソルだけ縦に1秒ずつ動いているのが確認できました。

個人的な考え

配列strの中に一文字ずつtimer_strの中身を入れて最後に文字としてまとめて表示するのかな?と考えています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

 void timer_data_1(char timer_str)
 {
-    int i = 0;
-    int flag = 0;
+    static int i = 0;
+    static int flag = 0;

     if (timer_str == STX){
         flag = 1;
     }else if (timer_str == ETX){
-        printf("%c\n", str);
+        printf("%s\n", str);
         flag = 0;
+        i = 0;
-    }else if (flag = 1){
-        str[int_c[i]] = timer_str + (i + 1);
+     }else if (flag == 1){
+        str[int_c[i]] = timer_str;
         i++;
     }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/17 04:13

    教えてくださりありがとうございます。上記のプログラムのelse if (timer_str == ETX)の部分を
    else if (timer_str == ETX && i == 14)と変えてみたら表示例のように正しく表示することができました。

    キャンセル

+1

        sprintf(str + 1,"%04d%02d%02d%02d%02d%02d",

表示する文字列を生成してるのはわかるのですが、
それをプリントアウト(表示)しているところが見当たりません

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

static int int_c[] = { 0, 1, 2, 3, 6, 7, 10, 11, 16, 17, 20, 21, 24, 25};    /* 上の配列strの間接的な添え字 */

何故全角文字(年、月など)が2バイトなんでしょう?
・・・UNIX系OS(LinuxやMac)じゃダメですよ・・・

書式を変えましょう↓
"%04d%02d%02d%02d%02d%02d"→"%04d年%02d月%02d日  %02d時%02d分%02d秒"

蛇足ながら、『関数にする必要ありますか?』
追記:ただ、表示するだけで良ければ・・・

#include <stdio.h>
#include <unistd.h>
#include <time.h>
//
int main( )
{
    time_t     current;
    struct tm *timer;
    int        tm_sec = 0;
    char       str[256];
    //
    while(1) {
        current = time(NULL);
        timer   = localtime(&current);
        if(timer->tm_sec != tm_sec) {
            sprintf(str, "%04d年%02d月%02d日  %02d時%02d分%02d秒",
                    timer->tm_year + 1900, timer->tm_mon + 1, timer->tm_mday,
                    timer->tm_hour, timer->tm_min, timer->tm_sec);
            puts(str);
            tm_sec = timer->tm_sec;
        }
        sleep(1);
    }
    //
}


usr ~/Project/test % ./a.out
2020年07月16日  22時56分36秒
2020年07月16日  22時56分37秒
2020年07月16日  22時56分38秒
2020年07月16日  22時56分39秒
2020年07月16日  22時56分40秒
2020年07月16日  22時56分41秒
2020年07月16日  22時56分42秒
2020年07月16日  22時56分43秒
^C

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/16 22:53 編集

    あと、CPUの使用率も考慮して、表示しない時(空ループの時)は、sleep()関数などを利用してCPUを他のプロセスに開けてあげましょう。こちらで計測したCPU使用率は。空ループ:7%、sleep():1%でした。
    ※sleep()は、1秒単位でしか対応できないので何処かで誤差が出そう^^;

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る