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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

3回答

685閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2020/07/19 05:05

実現したい事

C言語で日時を複数文字取得して、表示する関数を作成したいです。
何日か前にも「日時を取得して、表示する関数を作成したい」と質問しましたがそれとは別です。

表示例

2020年07月19日 13時50分01秒
2020年07月19日 13時50分02秒
2020年07月19日 13時50分03秒
2020年07月19日 13時50分04秒
2020年07月19日 13時50分05秒
2020年07月19日 13時50分06秒
2020年07月19日 13時50分07秒
上のように1秒ずつ表示されるようにしたい

該当のソースコード

c

1#include <stdio.h> 2#include <time.h> 3 4#define STX 0x02 /* テキスト開始 */ 5#define ETX 0x03 /* テキスト終了 */ 6 7static char str[] = "9999年99月99日 99時99分99秒"; 8static int int_c[] = { 0, 1, 2, 3, 6, 7, 10, 11, 16, 17, 20, 21, 24, 25}; /* 上の配列strの間接的な添え字 */ 9 10/* 11 名称 timer_data_n 12 引数 char *timer_str:日時([STX]YYYYMMDDHHMMSS[ETX])中の複数文字 13 int timer_len:日時([STX]YYYYMMDDHHMMSS[ETX])中の文字数 14 戻り値 無し 15*/ 16/*----- ここより下に解答を記述してください -----*/ 17void timer_data_n(char *timer_str, int timer_len) 18{ 19 static int i = 0; 20 static int j; 21 static int flag = 0; 22 23 if (timer_str[i + 0] == STX){ 24 flag = 1; 25 }else if (timer_str[i + 0] == ETX && i == 14){ 26 printf("%s\n", str); 27 flag = 0; 28  i = 0; 29 }else if (flag == 1){ 30 for (j = 0; j < timer_len; j++){ 31 str[int_c[i]] = timer_str[i + 0]; 32 i++; 33 } 34 } 35 return; 36} 37/*----- ここより上に解答を記述してください -----*/ 38 39int main(void) 40{ 41 time_t current; 42 struct tm *timer; 43 int tm_sec = 0; 44 char str[20]; 45 int i, j, k; 46 char str_snd[20]; 47 48 /* 乱数の初期化 */ 49 srand(time(NULL)); 50 i = rand() % 15; 51 52 k = 0; 53 54 while(1){ 55 current = time(NULL); 56 timer = localtime(&current); 57 if(timer->tm_sec != tm_sec){ 58 *(str + 0) = STX; 59 sprintf(str + 1,"%04d%02d%02d%02d%02d%02d", 60 timer->tm_year + 1900, timer->tm_mon + 1, timer->tm_mday, 61 timer->tm_hour, timer->tm_min, timer->tm_sec); 62 *(str + 15) = ETX; 63 *(str + 16) = '\0'; 64 65 while(*(str+i)){ 66 /* 乱数の初期化 */ 67 srand(time(NULL)); 68 j = rand() % 6 + 1; 69 70 while(k < j){ 71 if(i >= 16){ 72 break; 73 } 74 75 str_snd[k] = *(str + i); 76 i++; 77 k++; 78 } 79 str_snd[k] = 0; 80 81 timer_data_n(str_snd, k); 82 83 k = 0; 84 } 85 86 tm_sec = timer->tm_sec; 87 i = 0; 88 } 89 } 90 91 return 0; 92}

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

コンパイルエラーは起きていませんが何も表示されません。関数部分のプログラムは、何日か前に質問した「日時を取得して、表示する関数を作成したい」、の関数を一部変えて使いまわしています。詳しくは実際に記事を見ていただければ嬉しいです。前回の時とは違い、カーソルも全く反応しないので何がいけないのかわからないので教えてほしいです。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

  • srcを書き替えるときに、timer_strのインデックスはiでなくjで処理する。
  • timer_strの先頭にSTXがあっても、2文字目以降があればsrcを書き替える。そのときは、先頭のSTXを除いて処理しないといけない。
  • timer_lenの長さだけ常にsrcを書き替えていると、timer_strの末尾にETXがある場合、int_cの要素数を超えてアクセスすることになる。
  • timer_strの先頭にETXが来るとは限らない。末尾にETXがあるかをチェックすべき。

C

1void timer_data_n(char *timer_str, int timer_len) { 2 static int i = 0; 3 static int flag = 0; 4 5 int j = 0; 6 if (timer_str[0] == STX) { 7 flag = 1; 8 j = 1; 9 } 10 if (flag == 1) { 11 for (; j < timer_len && i < 14; j++) { 12 str[int_c[i]] = timer_str[j]; 13 i++; 14 } 15 if (timer_str[timer_len - 1] == ETX) { 16 printf("%s\n", str); 17 flag = 0; 18 i = 0; 19 } 20 } 21 return; 22}

投稿2020/07/19 08:38

Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/07/19 09:21

細かく説明してくださりありがとうございます。 本当にわからなかったのでとても助かりました。
guest

0

/----- ここより下に解答を記述してください -----/

void timer_data_n(char *timer_str, int timer_len)
{
...
if (timer_str[i + 0] == STX){
flag = 1;

timer_str[0] にはSTXしか入ってませんので、この条件ぶんは常に真となり、printfは実行されることはありません。

まあ、なにをしたいのかはよーわかりませんが、とりあえず、なにか表示されるということはないですね

投稿2020/07/19 06:27

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/07/19 06:55

ありがとうございます。合ってるかわかりませんがプログラムについてもうちょっと説明します。 main関数で最初に現在の年・月・日・時・分・秒を読み込んで配列strに格納(20200719154216)。 while(*(str+i))の部分での処理で配列str_sndに(20200719154216)の中からランダムで選んだ数字をj回ぶん入れているんだと思います。その後に関数内の処理で配列strの中に1つづつ入れている感じです。 前回の質問の「日時を取得・表示」のプログラムを表示で作成した関数の処理を少し変えればいいかと思ったんですが、それがなぜかできないといった状況です。
退会済みユーザー

退会済みユーザー

2020/07/19 06:59

すいません。デバッグで見てみたのですが「while(*(str+i))の部分での処理で配列str_sndに(20200719154216)の中からランダムで選んだ数字をj回ぶん入れているんだと思います。」の部分、説明が違うかもしれないです。よく分かりませんでした・・・
y_waiwai

2020/07/19 07:03

まあ、Cのコードを書くなら、VisualStudioなんかでデバッグできる環境を整えて、1行づつ実行できるようにしましょう。 なにが起きてるのか、ってのがわかるようになります
退会済みユーザー

退会済みユーザー

2020/07/19 07:14

visual C++ 2008 express edition を使ってます。 わからないのは上記のjの部分となんで表示されないのか だけです。処理自体は大きく変えなくてもいいような気がするんですが・・・
y_waiwai

2020/07/19 07:30

乱数を扱うなら、srand のところに定数を入れてやれば、以降の乱数は同一値が出てきてくれますんで、デバッグやりやすくなります ただ、提示のコードの2番めのsrandの記述は削除しましょう。 これは不要です
guest

0

timer_data_nの引数の文字列を1文字ずつ前回のtimer_data_1に渡してやれば完了だと思われます。
(課題と思われますがそういった回答が禁止なら補足してください)

投稿2020/07/19 06:22

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/07/19 07:03

一応関数内でfor文 回して1文字ずつ、件数ぶんstrに入れているんですが違うってことですかね? 後、そういった回答は禁止ではないです。
hope_mucci

2020/07/19 08:49

まあ、違っているから予想とは異なる結果が返ってきているわけで。 time_strに何が入ってくるかをきちんと理解しているでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問